29.1實驗內容
通過本實驗主要學習以下內容:
- USB IAP升級操作
29.2實驗原理
USB IAP升級本例程中使用的是Custom HID中的IAP設備類,其設備類協(xié)議的實現與HID的類似,主要包括GET_REPORT/GET_IDLE/GET_PROTOCOL/SET_REPORT/SET_IDLE/SET_PROTOCOL/USB_GET_DESCRIPTOR等。IAP的功能為通過USB接口通信的方式對app端代碼進行更新。
29.3硬件設計
USB虛擬鍵盤實驗章節(jié)已介紹。
29.4代碼解析
IAP主函數如下所示,開始主要為delay延遲配置以及按鍵配置,之后判斷KEY1按鍵是否被按下,如果KEY1按鍵沒被按下,將會進入到跳轉代碼段,如果APP_LOADED_ADDR(0x08008000U)地址中有對應APP的堆棧指針,則認為APP段有數據可直接跳轉執(zhí)行。如果堆棧指針校驗異常,則跳出判斷執(zhí)行后續(xù)代碼;如果KEY1按鍵被按下,則跳過跳轉語句段,直接運行USB IAP的升級代碼。通過RCU/USB等相關配置后,在PC端將會識別一個USB IAP設備。
C int main(void) { uint32_t app_address; app_func application; uint32_t sram_sect = REG32(APP_LOADED_ADDR); driver_init(); /* configure KEY1 key to run firmware */ bsp_key_init(&KEY1); /* KEY1 key must be pressed on board when power on */ if(SET !=bsp_key_state_get(&KEY1)) { /* test if user code is programmed starting from address 0x8008000 */ if((sram_sect >= SRAM_BASE_ADDR) && (sram_sect < SRAM_END_ADDR)){ app_address = *(__IO uint32_t*) (APP_LOADED_ADDR + 4U); application = (app_func) app_address; /* initialize user application's stack pointer */ __set_MSP(*(__IO uint32_t*) APP_LOADED_ADDR); /* jump to user application */ application(); } } /* system clocks configuration */ rcu_config(); /* GPIO configuration */ gpio_config(); /* USB device configuration */ usbd_init(&usbd_iap, &iap_desc, &iap_class); /* NVIC configuration */ nvic_config(); /* enabled USB pull-up */ usbd_connect(&usbd_iap); while (1){ } } |
HID報文描述符如下所示,該報文描述符描述了收發(fā)數據類型以及長度,其中,主機發(fā)送的IAP命令和數據長度為63個字節(jié),MCU從機回復的狀態(tài)數據長度為16個字節(jié)。
C const uint8_t iap_report_desc[USB_DESC_LEN_IAP_REPORT] = { 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ 0x09, 0x00, /* USAGE (Custom Device) */ 0xa1, 0x01, /* COLLECTION (Application) */ /* IAP command and data */ 0x85, 0x01, /* REPORT_ID (0x01) */ 0x09, 0x01, /* USAGE (IAP command) */ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ 0x25, 0xff, /* LOGICAL_MAXIMUM (255) */ 0x75, 0x08, /* REPORT_SIZE (8) */ 0x95, 0x3f, /* REPORT_COUNT (63) */ 0x91, 0x82, /* OUTPUT (Data,Var,Abs,Vol) */ /* device status and option byte */ 0x85, 0x02, /* REPORT_ID (0x02) */ 0x09, 0x02, /* USAGE (Status and option byte) */ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ 0x25, 0xff, /* LOGICAL_MAXIMUM (255) */ 0x75, 0x08, /* REPORT_SIZE (8) */ 0x95, 0x10, /* REPORT_COUNT (16) */ 0x81, 0x82, /* INPUT (Data,Var,Abs,Vol) */ 0xc0 /* END_COLLECTION */ }; |
MCU接收到主機發(fā)送的數據后,將會進入iap_data_out回調函數,其中實現了IAP download(數據下載)、IAP Erase(擦除操作)、IAP OPTION BYTE(獲取選項字節(jié))、IAP LEAVE(退出IAP模式)、IAP GETBIN ADDRESS(獲取APP起始地址)幾個功能。
C static void iap_data_out (usb_dev *udev ,uint8_t ep_num) { usbd_iap_handler *iap = (usbd_iap_handler *)udev->class_data[USBD_IAP_INTERFACE]; if (0x01U == iap->report_buf[0]) { switch(iap->report_buf[1]) { case IAP_DNLOAD: iap_req_dnload(udev); break; case IAP_ERASE: iap_req_erase(udev); break; case IAP_OPTION_BYTE: iap_req_optionbyte(udev); break; case IAP_LEAVE: iap_req_leave(udev); break; case IAP_GETBIN_ADDRESS: iap_address_send(udev); break; default: break; } } usbd_ep_recev(udev, IAP_OUT_EP, iap->report_buf, IAP_OUT_PACKET); } |
29.5實驗結果
將本實驗歷程燒錄到紅楓派開發(fā)板中,打開GD32 ALL IN One上位機,如下圖所示,接口選擇USB,Bootloader協(xié)議選擇IAP,之后點擊connect進行連接。
連接成功后,顯示如下圖所示,connect按鈕變成disconnect,且在左下角顯示芯片信息。
右側欄目即為USB IAP可實現的功能,主要包括載升級代碼,其他功能為灰色不能操作。點擊Browse選擇下載bin或者hex文件,之后點擊download即可進行下載,下載完成后,進度條顯示100%,即完成升級下載。
本教程由GD32 MCU方案商聚沃科技原創(chuàng)發(fā)布,了解更多GD32 MCU教程,關注聚沃科技官網
-
單片機
+關注
關注
6034文章
44543瀏覽量
634213 -
usb
+關注
關注
60文章
7927瀏覽量
264358 -
開發(fā)板
+關注
關注
25文章
5017瀏覽量
97336 -
IAP
+關注
關注
2文章
163瀏覽量
24275 -
GD32
+關注
關注
7文章
403瀏覽量
24303
發(fā)布評論請先 登錄
相關推薦
評論