Loading...
首页专栏正文

STM32 CANbootloader 升级功能设计开发(3)主要逻辑功能实现

 
1人已赏
free-jdx 发布于 2020-11-26 18:25:09 浏览 4759 点赞 73 收藏 17

1. 前言

最后这部分内容,主要是一些逻辑关键功能; 例如,

  • bootloader如何调整到app地址段执行?
  • 如何解析CAN数据?
  • 如何防止CAN设备变砖?

2. bootloader跳转app功能实现

app起始地址0x8004000 bootloader的烧写地址仍是0x08000000

(1)修改app程序相关设置

keil软件编译时需要修改烧写地址成8004000

keil进入Linker点击“edit”,修改源码改为0x08004000

(2)bootloader跳转接口实现

    if(*((uint32_t *)EXE_FLAG_START_ADDR)== EXE_FLASH_MAGICNUMBER )
    {
        JumpToApplication(START_ADDR);
    }

接口实现如下: 注意: 跳转之前必须清楚外设状态,避免外设初始化冲突

void CAN_BOOT_JumpToApplication(uint32_t Addr)
{
  static pFunction Jump_To_Application;
  __IO uint32_t JumpAddress; 
  /* Test if user code is programmed starting from address "ApplicationAddress" */
  if (((*(__IO uint32_t*)Addr) & 0x2FFE0000 ) == 0x20000000)
  { 
    /* Jump to user application */
    JumpAddress = *(__IO uint32_t*) (Addr + 4);
    Jump_To_Application = (pFunction) JumpAddress;
    __set_PRIMASK(1);
    /* Initialize user application's Stack Pointer */
    __set_MSP(*(__IO uint32_t*)Addr);

    /*must reset£¬or can not succeed to jump to App/UpBootloader*/
    MX_CAN_DeInit();
    MX_GPIO_DeInit();
    HAL_DeInit();

    Jump_To_Application();
  }
}

(3)app程序设置部分

  • 重定位中断向量表

  • 开启所有中断

  • 复位RCC

进入main函数时,设置如下:

    SCB->VTB = 0x08004000;

    __set_PRIMASK(0);

    HAL_RCC_DeInit();

3. CAN命令解析

(1)通过CAN接收中断设置的标志位进行判断

    if(CanRxFlag){
      CAN_ExecutiveCmd(&RxBuf);
      CanRxFlag = 0;
    }

(2)CAN cmd定义

CBL_CMD_LIST CMD_List = 
{
  .Erase = 0x00,      //擦除
  .WriteInfo = 0x01,  //设置参数
  .Write = 0x02,      //写数据
  .Check = 0x03,      //检测节点是否在线
  .SetBaudRate = 0x04,    //设置波特率
};

具体如何解析CAN 命令,这里就不累述了,比较简单

3. 添加强制刷机功能

原因:这里主要是用于CAN设备如果出现系统错误,无法正常进入bootloader之后,变成砖

方法: 进入bootloader会响应一个上位机的强制刷机命令,如果接收到,就强制擦除环境变量,然后强制进入bootloader,避免成砖;

实现如下:

    do
    {
        HAL_Delay(1);
        i++;
        if (CanRxFlag)
        {
            if (0x84 ==RxBuf.StdId)
            {
                {
                    HAL_FLASH_Unlock();
                    FLASH_PageErase(APP_START_ADDR);
                    HAL_FLASH_Lock();
                    break;
                }
            }           
        }
        if(1000 < i)
        {
            break;
        }
    }
    while (1);

*本文仅代表作者观点,不代表易百纳技术社区立场。系作者授权易百纳技术社区发表,未经许可不得转载。

精彩评论

内容存在敏感词
打赏
打赏作者
free-jdx
您的支持将鼓励我继续创作!
金额:
¥1 ¥5 ¥10 ¥50 ¥100
支付方式:
微信支付
支付宝支付
微信支付
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

易百纳技术社区
确定要删除此文章、专栏、评论吗?
确定
取消
易百纳技术社区