1. Bootloader基础架构搭建
任务目标
搭建一个最小化的AUTOSAR Bootloader工程框架,包含内存映射、启动流程和主函数循环。该框架作为后续刷写案例的基础,仅实现地址重映射与跳转逻辑,不包含具体刷写协议处理。
内存映射设计
Bootloader与App共享同一Flash,通过链接脚本划分地址空间。本案例使用GCC链接脚本,目标MCU为Infineon AURIX TC275(TriCore架构),实际项目中需按芯片调整地址。
/* bootloader.ld - 最小Bootloader链接脚本 */
MEMORY
{
/* PFlash0: Bootloader区 0x80000000 - 0x8000FFFF (64KB) */
/* PFlash1: App区起始 0x80100000 */
BOOT_FLASH (rx) : ORIGIN = 0x80000000, LENGTH = 64K
APP_FLASH (rx) : ORIGIN = 0x80100000, LENGTH = 1M
RAM (rwx) : ORIGIN = 0x60000000, LENGTH = 192K
}
SECTIONS
{
.text :
{
*(.text.start) /* 启动入口 */
*(.text*)
} > BOOT_FLASH
.rodata : { *(.rodata*) } > BOOT_FLASH
.data : { *(.data*) } > RAM AT > BOOT_FLASH
.bss : { *(.bss*) } > RAM
}
启动流程与主函数
启动流程包含:硬件初始化、栈指针设置、跳转条件判断。主函数循环中仅保留跳转检测逻辑,实际刷写命令处理在后续案例中扩展。
/* boot.c - 最小Bootloader实现 */
#include <stdint.h>
/* App起始地址(与链接脚本APP_FLASH一致) */
#define APP_START_ADDR 0x80100000U
/* 跳转标志:位于RAM固定地址,由App或外部工具设置 */
#define JUMP_FLAG_ADDR 0x60000000U
#define JUMP_FLAG_VALUE 0xA5A5A5A5U
typedef void (*AppMainFunc)(void);
/* 启动入口(链接脚本中.text.start段) */
__attribute__((section(".text.start")))
void Boot_Start(void)
{
/* 1. 关闭中断 */
__disable_interrupt();
/* 2. 检查跳转标志 */
volatile uint32_t *jumpFlag = (volatile uint32_t *)JUMP_FLAG_ADDR;
if (*jumpFlag == JUMP_FLAG_VALUE)
{
/* 3. 清除跳转标志 */
*jumpFlag = 0U;
/* 4. 跳转到App */
AppMainFunc appEntry = (AppMainFunc)(*(volatile uint32_t *)(APP_START_ADDR + 4U));
appEntry();
}
else
{
/* 5. 进入Bootloader主循环 */
Boot_MainLoop();
}
}
/* Bootloader主函数循环 */
void Boot_MainLoop(void)
{
while (1U)
{
/* 轮询跳转标志(实际刷写命令处理在此扩展) */
volatile uint32_t *jumpFlag = (volatile uint32_t *)JUMP_FLAG_ADDR;
if (*jumpFlag == JUMP_FLAG_VALUE)
{
*jumpFlag = 0U;
AppMainFunc appEntry = (AppMainFunc)(*(volatile uint32_t *)(APP_START_ADDR + 4U));
appEntry();
break;
}
}
}
/* 中断禁用(TriCore内联汇编) */
static inline void __disable_interrupt(void)
{
__asm__ volatile ("disable");
}
编译与验证
编译命令:
tricore-gcc -c boot.c -o boot.o -mcpu=tc275
tricore-ld -T bootloader.ld boot.o -o boot.elf
tricore-objcopy -O ihex boot.elf boot.hex
验证方法:
- 检查生成的
boot.hex起始地址是否为0x80000000,确认链接脚本生效。 - 在调试器中加载
boot.elf,将0x60000000地址写入0xA5A5A5A5,单步执行应跳转到0x80100004处(App入口)。 - 不设置跳转标志时,程序应停留在
Boot_MainLoop的while循环中。
通过条件:程序能按标志位正确选择进入Bootloader循环或跳转App,且链接映射地址与设计一致。