最近在搞調試器,折騰了好多天,終于理解了MDK、下載算法、調試器、MCU之間的關系。
簡單來說就是,調試器作為USB轉SWD協議的轉換工具,MDK通過USB驅動這個工具,下載算法包含了一些MCU內部FLASH擦除、編程代碼。與普通代碼不同的是,該代碼可以下載在任意位置運行。如果需要校驗,還會加入CRC校驗代碼,扇區檢測代碼。
MDK首先通過調試器將算法寫入內部RAM,然后把需要寫入的固件程序寫入RAM,再由MDK控制(通過調試器)MCU執行相應代碼(擦除或寫入扇區),通過MCU的寄存器和設定軟件斷點得到執行結果,如此來回搬運,就可完成固件下載。
說起來簡單,做起來很麻煩(調試器工具功能簡單,只做協議轉換,如何控制通過MDK),這里點到為止,有時間會好好整理分享一下。
之后準備USB相關的工作,發現總是沒有滿意的USB CORE庫,官方的庫感覺還不錯,可惜被封裝了,看不到源碼,放棄。
之前魚鷹分享過虛擬串口的代碼,于是下載下來使用,發現竟然在GD32中用不了,當初明明ST測試沒問題的。
還以為是GD芯片問題,然后使用之前的USB雙緩沖讀卡器代碼,發現沒有問題。
只能在線調試比較差異,借助邏輯分析儀,總算解決了這兩個BUG,順利自發自收。
BUG 1
枚舉失敗。
通過邏輯分析儀發現,電腦發送控制幀給USB設備,竟然沒有任何回應,即沒有NAK,也米有STALL,更不用說ACK了。
▲正常回應
▲無回應
通過調試發現,該端點接收狀態為0,禁用狀態,再參考可用代碼,發現在復位之后,應該設置為接收有效才對。因此修改如下:
void USBD_Reset (void) { ……………… …… …… EPxREG(0)=EP_CONTROL|EP_RX_VALID;// 除了設定端點類型外,還要使能接收 DADDR = DADDR_EF | 0; /* Enable USB Default Address */ }
很奇怪的是,ST我以前測試是沒問題的,可能也是兩者之間的差異吧。
BUG2
枚舉成功后,又出現另外一個問題,就是串口只能發送第一幀數據,第二次卡死……
經過邏輯分析儀發現,發送的數據會被NAK。后來才發現下面的語句不滿足,直接沒有讀USB數據包,從而沒有恢復接收有效狀態,導致串口助手卡死。 這段官方代碼也確實比較迷,沒有最大利用緩存空間(最少需要滿一包的空間,但實際可能不滿一包),不過按下不表。 那就是第一次收到的數據未讀唄,在main()函數里面發現根本沒進來,發現竟然一直在USB中斷執行……
void main() { while(1) { …… if (usb_rx_ch == -1) usb_rx_ch = USBD_CDC_ACM_GetChar(); …… } }然后看到這個標志一直在,未清除導致。
但很奇怪的事,該代碼在ST里面跑的挺好的。不管它,加上處理:
void USB_LP_CAN1_RX0_IRQHandler(void) { …… if (istr & ISTR_ESOF) { if (USBD_P_Error_Event) { USBD_P_Error_Event(3); } ISTR = ~ISTR_ESOF; } …… }
這下串口助手一下子絲滑了,舒服!
審核編輯:湯梓紅
-
mcu
+關注
關注
146文章
16984瀏覽量
350294 -
寄存器
+關注
關注
31文章
5317瀏覽量
120002 -
調試器
+關注
關注
1文章
300瀏覽量
23689 -
虛擬串口
+關注
關注
3文章
62瀏覽量
13866 -
GD32
+關注
關注
7文章
403瀏覽量
24219
原文標題:關于GD32虛擬串口的兩個BUG
文章出處:【微信號:玩點嵌入式,微信公眾號:玩點嵌入式】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論