[研电赛技术支持] 【GD32F303红枫派使用手册】第二十九讲 USB-IAP升级实验

[复制链接]
1839|0
 楼主| 聚沃科技 发表于 2024-7-4 09:50 | 显示全部楼层 |阅读模式
红枫派首图.png
29.1 实验内容
通过本实验主要学习以下内容:
• USB IAP升级操作
29.2 实验原理
USB IAP升级本例程中使用的是Custom HID中的IAP设备类,其设备类协议的实现与HID的类似,主要包括GET_REPORT/GET_IDLE/GET_PROTOCOL/SET_REPORT/SET_IDLE/SET_PROTOCOL/USB_GET_DESCRIPTOR等。IAP的功能为通过USB接口通信的方式对app端代码进行更新。
29.3 硬件设计
USB虚拟键盘实验章节已介绍。
29.4 代码解析
IAP主函数如下所示,开始主要为delay延迟配置以及按键配置,之后判断KEY1按键是否被按下,如果KEY1按键没被按下,将会进入到跳转代码段,如果APP_LOADED_ADDR0x08008000U)地址中有对应APP的堆栈指针,则认为APP段有数据可直接跳转执行。如果堆栈指针校验异常,则跳出判断执行后续代码;如果KEY1按键被按下,则跳过跳转语句段,直接运行USB IAP的升级代码。通过RCU/USB等相关配置后,在PC端将会识别一个USB IAP设备。
  1. C
  2. int main(void)
  3. {
  4.     uint32_t app_address;
  5.     app_func application;
  6.     uint32_t sram_sect = REG32(APP_LOADED_ADDR);
  7.         
  8.           driver_init();

  9.     /* configure KEY1 key to run firmware */
  10.           bsp_key_init(&KEY1);

  11.     /* KEY1 key must be pressed on board when power on */
  12.     if(SET !=bsp_key_state_get(&KEY1)) {
  13.         /* test if user code is programmed starting from address 0x8008000 */
  14.         if((sram_sect >= SRAM_BASE_ADDR) && (sram_sect < SRAM_END_ADDR)){
  15.             app_address = *(__IO uint32_t*) (APP_LOADED_ADDR + 4U);
  16.             application = (app_func) app_address;

  17.             /* initialize user application's stack pointer */
  18.             __set_MSP(*(__IO uint32_t*) APP_LOADED_ADDR);

  19.             /* jump to user application */
  20.             application();
  21.         }
  22.     }

  23.     /* system clocks configuration */
  24.     rcu_config();

  25.     /* GPIO configuration */
  26.     gpio_config();

  27.     /* USB device configuration */
  28.     usbd_init(&usbd_iap, &iap_desc, &iap_class);

  29.     /* NVIC configuration */
  30.     nvic_config();

  31.     /* enabled USB pull-up */
  32.     usbd_connect(&usbd_iap);

  33.     while (1){
  34.     }
  35. }
HID报文描述符如下所示,该报文描述符描述了收发数据类型以及长度,其中,主机发送的IAP命令和数据长度为63个字节,MCU从机回复的状态数据长度为16个字节。
  1. C
  2. const uint8_t iap_report_desc[USB_DESC_LEN_IAP_REPORT] =
  3. {
  4.     0x05, 0x01,     /* USAGE_PAGE (Generic Desktop) */
  5.     0x09, 0x00,     /* USAGE (Custom Device)        */
  6.     0xa1, 0x01,     /* COLLECTION (Application)     */

  7.     /* IAP command and data */
  8.     0x85, 0x01,     /* REPORT_ID (0x01)          */
  9.     0x09, 0x01,     /* USAGE (IAP command)       */
  10.     0x15, 0x00,     /* LOGICAL_MINIMUM (0)       */
  11.     0x25, 0xff,     /* LOGICAL_MAXIMUM (255)     */
  12.     0x75, 0x08,     /* REPORT_SIZE (8)           */
  13.     0x95, 0x3f,     /* REPORT_COUNT (63)         */
  14.     0x91, 0x82,     /* OUTPUT (Data,Var,Abs,Vol) */

  15.     /* device status and option byte */  
  16.     0x85, 0x02,     /* REPORT_ID (0x02)               */
  17.     0x09, 0x02,     /* USAGE (Status and option byte) */
  18.     0x15, 0x00,     /* LOGICAL_MINIMUM (0)            */
  19.     0x25, 0xff,     /* LOGICAL_MAXIMUM (255)          */
  20.     0x75, 0x08,     /* REPORT_SIZE (8)                */
  21.     0x95, 0x10,     /* REPORT_COUNT (16)              */
  22.     0x81, 0x82,     /* INPUT (Data,Var,Abs,Vol)       */

  23.     0xc0            /* END_COLLECTION            */
  24. };
MCU接收到主机发送的数据后,将会进入iap_data_out回调函数,其中实现了IAP download(数据下载)、IAP Erase(擦除操作)、IAP OPTION BYTE(获取选项字节)、IAP LEAVE(退出IAP模式)、IAP GETBIN ADDRESS(获取APP起始地址)几个功能。
  1. C
  2. static void iap_data_out (usb_dev *udev ,uint8_t ep_num)
  3. {
  4.     usbd_iap_handler *iap = (usbd_iap_handler *)udev->class_data[USBD_IAP_INTERFACE];

  5.     if (0x01U == iap->report_buf[0]) {
  6.         switch(iap->report_buf[1]) {
  7.         case IAP_DNLOAD:
  8.             iap_req_dnload(udev);
  9.             break;

  10.         case IAP_ERASE:
  11.             iap_req_erase(udev);
  12.             break;

  13.         case IAP_OPTION_BYTE:
  14.             iap_req_optionbyte(udev);
  15.             break;

  16.         case IAP_LEAVE:
  17.             iap_req_leave(udev);
  18.             break;

  19.         case IAP_GETBIN_ADDRESS:
  20.             iap_address_send(udev);
  21.             break;

  22.         default:
  23.             break;
  24.         }
  25.     }

  26.     usbd_ep_recev(udev, IAP_OUT_EP, iap->report_buf, IAP_OUT_PACKET);
  27. }
29.5 实验结果
将本实验历程烧录到红枫派开发板中,打开GD32 ALL IN One上位机,如下图所示,接口选择USBBootloader协议选择IAP,之后点击connect进行连接。
图片8.png
连接成功后,显示如下图所示,connect按钮变成disconnect,且在左下角显示芯片信息。
图片9.png
右侧栏目即为USB IAP可实现的功能,主要包括载升级代码,其他功能为灰色不能操作。点击Browse选择下载bin或者hex文件,之后点击download即可进行下载,下载完成后,进度条显示100%,即完成升级下载。
图片10.png

本教程由GD32 MCU方案商聚沃科技原创发布,了解更多GD32 MCU教程,关注聚沃科技官网,GD32MCU技术交流群:859440462

您需要登录后才可以回帖 登录 | 注册

本版积分规则

170

主题

190

帖子

13

粉丝
快速回复 在线客服 返回列表 返回顶部