打印
[方案相关]

[白泽开发板] 小华HC32F460 I2C bootloader和上位机程序分享

[复制链接]
2485|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 MCU@Baize 于 2024-1-12 17:39 编辑

#申请原创# #技术资源#

时间过得真快,不知不觉就进入到2024年了。近期抽空写了一个HC32F460 I2C 的bootloader和上位机程序,分享出来。欢迎拍砖,^_^
首先在进入main,代码封装好了,看起来比较清爽。分别是初始化和boot任务。
int32_t main(void)
{
   bootloader_init();//初始化
   while(1)
   {      
       bootloader_thread();//boot任务
    }
}
初始化里,会初始化GPIO,时钟和I2C,然后检测一下boot参数,有需要的话可以直接跳转到app区。
void bootloader_init(void)
{
   LL_PERIPH_WE(LL_PERIPH_ALL);
   gpio_init();//GPIO初始化
   BSP_CLK_Init();//时钟初始化
   i2c_init();//I2C模块实始化  
   LL_PERIPH_WP(LL_PERIPH_ALL);
   check_boot();//检查boot参数,做跳转
   m_boot.checksum = 0;
   m_boot.Status = Status_Idle;
}
然后就是boot任务,任务里做了分支,处理不同的指令
void bootloader_thread(void)
{
   
   if(UserBuf.lenth != 0)
    {
       switch(UserBuf.data[0])
       {
           case CMD_CFG://配置参数
                bootconfig();
                break;
           case CMD_WRITE://写入数据
                bootwrite();
                break;
           case CMD_VERIFY://校验(未实现)
                bootverify();
                break;
           case CMD_VERSION://读取版本号
                bootversion();
                break;
           case CMD_JUMP://跳转
                bootjump();
                break;
           case CMD_RESET://复位
                bootreset();
           case CMD_ERASE://擦除
                booterase();
                break;
           case CMD_READ8://8位访问MCU内部资源
                bootread8();
                break;
           case CMD_READ16://16位访问MCU内部资源
                bootread16();
                break;
           case CMD_READ32://32位访问MCU内部资源
                bootread32();
                break;
       }
       UserBuf.lenth = 0;
    }
}
这里会有m_boot结构体来控制状态机。由m_boot.Status控制状态。
先来看一下配置参数命令服务函数。这里会将目标地址,bin文件长度等参数传进来。把状态设置为Status_Linkup;
static void bootconfig(void)
{
   m_boot.targetaddress = *(unsigned int *)&UserBuf.data[1];  
   m_boot.lenth = *(unsigned int *)&UserBuf.data[5];
   m_boot.targetaddress_end = m_boot.targetaddress + m_boot.lenth;
   m_boot.version = *(unsigned int *)&UserBuf.data[9];
   m_boot.Status = Status_Linkup;
    GPIO_SetPins(GPIO_PORT_D,GPIO_PIN_05);
   u8TxBuf[0] = 'a';
   u8TxBuf[1] = 'c';
   u8TxBuf[2] = 'k';
   u8TxBuf[3] = '.';
}
然后就是擦除指令。这里会将app用到的空间全部擦除一次。把状态设置为Status_Erase。
static void booterase(void)
{
   if(m_boot.Status == Status_Linkup)
    {
        for(int i = m_boot.targetaddress; i <m_boot.targetaddress+m_boot.lenth; )
       {
           FlashErasePage(i);
           i += 0x2000;
       }
       m_boot.Status = Status_Erase;
    }
   u8TxBuf[0] = 'a';
   u8TxBuf[1] = 'c';
   u8TxBuf[2] = 'k';
   u8TxBuf[3] = '.';
}
接着是写flash数据。Flash必须先擦后写,因此在擦除指令执行前,不允许写数据。
static void bootwrite(void)
{
   if(m_boot.Status == Status_Erase)
    {
       unsigned int address, lenth;
       address = *(unsigned int *)&UserBuf.data[1];
        lenth = *(unsigned int*)&UserBuf.data[5];
       FlashWritePage(address,&UserBuf.data[9],lenth);
    }
   u8TxBuf[0] = 'a';
   u8TxBuf[1] = 'c';
   u8TxBuf[2] = 'k';
   u8TxBuf[3] = '.';
}
最后就是跳转指令,重要的时跳转前把外设反初始化,设置中断向量表偏移地址。
static void bootjump(void)
{
   IAP_JumpToApp(m_boot.targetaddress);
}
static int32_t IAP_JumpToApp(uint32_tu32Addr)
{
   uint32_t JumpAddress;

   /* Check if user code is programmed starting from address"u32Addr" */
   /* Check stack top pointer. */
       system_deInit();
       /* Jump to user application */
       JumpAddress = *(__IO uint32_t *)(u32Addr + 4);
       JumpToApplication = (func_ptr_t)JumpAddress;
       /* Initialize user application's Stack Pointer */
       __set_MSP(*(__IO uint32_t *)u32Addr);
       /* Rebase the vector table base address */
       SCB->VTOR = ((uint32_t) u32Addr & SCB_VTOR_TBLOFF_Msk);//设置中断向量表偏移地址
       /* Jump to application Reset Handler in the application */
       JumpToApplication();

   return 0;
}
最终效果

本次所使用的工具如下:
白泽USB转I2C工具 https://m.tb.cn/h.5m2udJO?tk=10MSWUUnOvW

HC32F460PETB 核心板 https://m.tb.cn/h.5NPZFJZ?tk=BViYWUUmKkB

上位机软件也有相关链接,感谢支持。
在此附上MCU工程代码和上位机源代码(上位机工程文件太大,上传失败,若有需要,可以进QQ群:961899436 或者加QQ:3140430649获取,备注需要BootLoader工程文件),供二次开发。


最后提示一下连接方式:例程SCL接PE15,SDA接PB5
#define I2C_SCL_PORT                    (GPIO_PORT_E)
#define I2C_SCL_PIN                     (GPIO_PIN_15)
#define I2C_SDA_PORT                    (GPIO_PORT_B)
#define I2C_SDA_PIN                     (GPIO_PIN_05)

就到这里了,大家有疑问回帖交流啦,<(* ̄▽ ̄*)/



淘宝店铺:打开淘宝,搜索“白泽开发板
各类国产品牌MCU评估板(小华、GD,持续更新中。。。。。。),以及USB转UART_I2C_SPI串行口调试模块:

【淘宝】https://m.tb.cn/h.5aGeMF8?tk=Okj0ds6cghX CZ0001 「华大开发板,HC32F4A0SITB,核心板,国产,研发调试」
点击链接直接打开 或者 淘宝搜索直接打开

【淘宝】https://m.tb.cn/h.5NPZFJZ?tk=BViYWUUmKkB CZ3457 「华大开发板 HC32F460PETB 核心板 调试研发」
点击链接直接打开 或者 淘宝搜索直接打开

【淘宝】https://m.tb.cn/h.5aCN4a4?tk=sF14dsQXD6p CZ0001 「小华  HC32F448MCTI 核心板  开发板 工程板」
点击链接直接打开 或者 淘宝搜索直接打开

【淘宝】https://m.tb.cn/h.5m2udJO?tk=10MSWUUnOvW CZ3457 「USB转UART_I2C_SPI串行口模块」
点击链接直接打开 或者 淘宝搜索直接打开


i2c_slave_bootloader.zip

5.84 MB

I2C_bootloader上位机源码.zip

14.85 KB

使用特权

评论回复
沙发
tpgf| | 2024-2-2 10:24 | 只看该作者
想要看懂这个程序还得结合具体的硬件连接

使用特权

评论回复
板凳
coshi| | 2024-2-2 10:59 | 只看该作者
能不能贴一下bootloader函数里边各种初始化函数的函数体内容呢

使用特权

评论回复
地板
qcliu| | 2024-2-3 09:58 | 只看该作者
感觉无论是谁家的开发板 样子好像都差别不大

使用特权

评论回复
5
drer| | 2024-2-3 10:30 | 只看该作者
有专用的usb转iic的转接芯片吗

使用特权

评论回复
6
kxsi| | 2024-2-3 11:11 | 只看该作者
相关配套资料里边应该会有电路板的版图

使用特权

评论回复
7
wiba| | 2024-2-3 11:47 | 只看该作者
我一直以为bootloader是不能直接写入代码里边的呢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

13

帖子

0

粉丝