s32k148 bootloader配置

       bootloader一般分为三个部分,上位机客户端,boot程序和App程序。

      上位机客户端软件:用来将mcu的app程序文件发送给mcu,发送的通讯方式有很多种,常见的如串口,can,甚至以太网。上位机发送的文件类型有很多种格式,如bin、hex、s19等。

       boot程序:boot程序的主要功能分为三部分,第一,接收客户端软件发来的程序;第二,将接收到的程序写入到mcu的flash中,即对片内flash进行编程;第三,跳转到App程序。

       App程序:就是我们正常运转的应用程序,和普通引用的程序不同的是它是由bootloader引导才开始执行的,不是reset之后执行的默认程序。

        对于客户端软件如何将app发送给mcu,方案非常多。以个人当前程序为例,就是上位机通过串口将程序bin文件发送给mcu,每次发送128字节,直至发送完成。在这里就不过多赘述。本文将以s32k如何将app程序写入片内flash和app程序跳转为重点讲述bootloader。


       将接收到的app程序写入mcu的flash,这个涉及到难点主要是mcu内部flash编程。s32k148有2M 程序flash,地址从0x00000000开始到0x00200000结束,其中每4kB又作为一个sector,且叫做扇区。flash编程主要涉及flash编程的初始化,扇区擦除,向flash写数据。这里我参考了这份代码,GitHub - Talendu/S32K144Bootloader: S32K14x系列单片机代码。首先初始化flash编程相关的时钟,然后初始化flash,flash_pflash_init();之后就是xmodem_write_image(uint8_t *p_data, uint16_t data_size)来对flash进行擦和写操作。在xmodem_write_image中主要用到flash_pflash_erase_sectors()和flash_write_PFLASH(),flash擦和写过程中,要关闭mcu中断。擦除操作最小单位是扇区,写的操作最小单位是8个字节,且这写操作的起始地址要以8字节为单位对齐。对于xmodem_write_image(...);调用需要注意几点,__g_flash_app_addr初始的设置要与4kb地址对齐,且4kb应该是每次写入flash数据长度的整数倍,如每次写入128kb,256kb等等,但是不要出现每次写入160kb,这虽满足与8字节想对齐,但是会遇到跨扇区编程的问题,就需要重新编写xmodem_write_image()函数。


void flash_clock_init(void)
{
    //开时钟门
    PCC->PCCn[PCC_FTFC_INDEX] |= PCC_PCCn_CGC_MASK;
    // 等待命令完成
    while((FTFC->FSTAT & FTFC_FSTAT_CCIF_MASK) != FTFC_FSTAT_CCIF_MASK);
    //启用写入缓冲区及cache
    LMEM->PCCCR = 0x85000001;
}
int main()
{
    ...
    flash_clock_init();
    flash_pflash_init();
    ...


   while(1)
   {
        if (get_program_data)
        {
           xmodem_write_image(...);
        }
        
   }
}


app程序跳转程序的跳转主要参考s32k144 bootloader - 纯洁de小学生 - 博客园。     

如何从bootloader程序跳转到App程序,见如下代码。注意这里的APP_ADDR与上文中__g_flash_app_addr初始化地址要保持一致。注意这里经试验证实不需要加入/* 设置栈顶指针*/ MSR_MSP(APP_ADDR);添加该代码反而无法实现跳转。

typedef void (*bootloader_fun)(void);          /*定义函数指针类型*/
bootloader_fun jump2app;                       /*定义函数指针*/
..........
/* 函数指针指向app的复位向量表的地址。注意将地址强转成函数入口地址 */
 jump2app = (bootloader_fun)*(uint32_t*)(APP_ADDR + 4);
 /*将pc指针指向入函数地址(app地址)运行*/
  jump2app();

作为app程序,也需要作出相应调整。

1、调整app程序的中断向量偏移地址

int main()
{ 
    /* 此处偏移地址必须和bootloader中的一样 */
    S32_SCB->VTOR = APP_ADDR;
    /* 关闭全局中断*/
    __asm volatile ("cpsie i" : : : "memory");

....
}

2、修改链接脚本,不同的ide,配置不一样,这里以s32DS为例,这里是APP程序.ld文件,红框中显示的偏移地址为0x2000,默认是0x0000.

APP程序修改完完成。

      为什么要修改app 中断偏移向量地址,不修改,App中断向量入口和bootloader将会重合,那么App程序将会调用bootloader的中断服务程序,这显然是不对的。

       至于为什么要修改链接脚本:函数的调用本质程序jump 到函数相应的入口地址而已。这个地址是什么,编译器是知道的,我们也可以通过map文件看到。同样的程序,如果链接脚本的偏移地址不一样,即使同一函数的访问地址也是不一样的。既然APP程序存储位置发生一定的偏移,就得告诉编译器偏移地址,不然编译器仍然以默认偏移地址生成函数的地址map,结果就是app 跳转到了错误的函数地址。

      最后向引用网址的两位作者表示由衷感谢。

  • 2
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
S32K148是恩智浦(NXP)公司推出的一款汽车级MCU,被广泛应用于汽车电子控制系统中。而s32k148bootloader源码则是其中的一个引导程序。引导程序是MCU启动时加载运行的第一个程序,它主要用于初始化硬件系统,加载应用程序并跳转到应用程序开始执行。 S32K148 Bootloader源码的主要作用是在S32K148芯片启动时,负责检测外部设备,如SD卡、USB等,然后加载相关的应用程序。它可以通过串口、CAN等方式通讯,更新MCU的固件程序,并支持MCU应用程序的自升级。 S32K148 Bootloader源码设计了一个应用程序区和一个引导程序区。引导程序区是存储引导程序的区域,应用程序区则是存放应用程序的区域。引导程序区和应用程序区可以通过配置修改大小和位置。 S32K148 Bootloader源码支持多种外部存储器,如SPI Flash、NAND Flash、SD卡、USB等,可以通过不同的芯片选择不同的启动方式,支持多种芯片的启动。同时,它还支持以下功能: 1. 可自动判断外部设备类型,支持自更新程序。 2. 支持数据保护,防止对程序区读、写、擦除等操作。 3. 支持断电恢复,即在应用程序升级过程中,如果断电或者中断,下一次启动时会自动从断点继续升级。 4. 支持多种设备之间的切换,支持读写SD卡、USB存储器、串口等多种通信协议。 总之,S32K148 Bootloader源码是一款功能强大的引导程序,它为S32K148芯片带来了更多的特色和优化,为汽车电子行业带来了更多的创新和便捷。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值