STM32F1 F4 USB 工程更新

現(xiàn)狀

  • 基于STM32CubeMX的F103/F40X的USB堆棧測(cè)試完畢;
  • 基于Mbed OS的F103/F40X的USB堆棧測(cè)試完畢;
  • 主要測(cè)試USB CDC設(shè)備;
  • 基于USB ACM/CDC實(shí)現(xiàn)nRF24L01及類(lèi)似“小無(wú)線(xiàn)”系統(tǒng)集成;
  • 基于USB ACM/CDC開(kāi)發(fā)了VT100 cmdline
  • 基于USB ACM/CDC和cmdline實(shí)現(xiàn)SPI NOR Flash的讀寫(xiě);
  • 基于USB ACM/CDC開(kāi)發(fā)HCI定制協(xié)議;
  • 基于Linux udev的USB設(shè)備插入拔出時(shí)間的檢測(cè);

計(jì)劃

  • 開(kāi)發(fā)其他TLV類(lèi)型二進(jìn)制協(xié)議和基于字符串的JSON RPC等協(xié)議;
  • 實(shí)現(xiàn)xmodem傳輸;
  • 實(shí)現(xiàn)I2C設(shè)備掃描與訪問(wèn);
  • 更新現(xiàn)有的LoRaPHY/Aloha/LoRaWAN USB Dongle;
  • 支持C8T6/RCT6等多種核心板,以應(yīng)對(duì)更加復(fù)雜的堆棧;
  • 支持USB ECM,以直接支持6LowPAN等物聯(lián)網(wǎng)設(shè)備;
  • 集成Arduino STM32的Bootloader實(shí)現(xiàn)固件升級(jí)。

開(kāi)源設(shè)計(jì)與板級(jí)產(chǎn)品

  • 大部分設(shè)計(jì)都是開(kāi)源設(shè)計(jì);
  • 或有根據(jù)客戶(hù)要求定制進(jìn)行設(shè)計(jì);

代碼設(shè)計(jì)過(guò)程

以下內(nèi)容針對(duì)Mbed C++和STM32F103/F407

今天完成的主要是在USB通道上實(shí)現(xiàn)VT100 cmdline,可以通過(guò)TeraTerm終端來(lái)配置管理設(shè)備,或者通過(guò)專(zhuān)門(mén)的cmd/GUI上位機(jī)程序?qū)崿F(xiàn)自動(dòng)化配置。最早基于C和串口,在Mbed Serial類(lèi)上移植也很容易。但是在USB信道上實(shí)現(xiàn)cmdline很花費(fèi)了一些時(shí)間,且有了反復(fù)。主要原因是USB對(duì)象初始化的特殊性,以及Mbed C++與基于標(biāo)準(zhǔn)庫(kù)或HAL庫(kù)的原始設(shè)計(jì)的差異所造成的。

基于標(biāo)準(zhǔn)庫(kù)或者HAL庫(kù)的模板一般是:

  • 將所需硬件資源(串口、GPIO)聲明為main的全局變量
  • 將USB聲明為 extern 全局變量
  • 在主函數(shù)中配置時(shí)鐘,初始化這些硬件資源
  • 展開(kāi)應(yīng)用邏輯

發(fā)現(xiàn)STM32 CubeMX的USB實(shí)例是usb_device.c中的全局變量。 這和一般的硬件資源如GPIO/ADC/PWM/CAN/UART都有所不同。

// Private in main.c
CAN_HandleTypeDef hcan;
RTC_HandleTypeDef hrtc;
UART_HandleTypeDef huart1;

int main(void){
  HAL_Init();
  SystemClock_Config();  // RCC init before any other resources
  MX_GPIO_Init();
  MX_CAN_Init();
  MX_USART1_UART_Init();
  MX_RTC_Init();
  MX_USB_DEVICE_Init();  // USB init here
  while(1){
    ...
  }
}

main.c

USBD_HandleTypeDef hUsbDeviceFS;

void MX_USB_DEVICE_Init(void)
{
  USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);
  USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC);
  USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS);
  USBD_Start(&hUsbDeviceFS);
}

usb_device.c

extern USBD_HandleTypeDef hUsbDeviceFS;

usb_device.h

而基于Mbed C++有些特殊。

DigitalOut myled(DBG_LED);  // See main.h for hardware issue
cmdline cmdhandler;
// You can put USBSerial/USBTerminal here, but will not be enumerated in F103
//USBSerial usbSerial(0x1f00, 0x2012, 0x0001,  false); 
USBTerminal *term;

int main(){
  confSysClock();  // RCC init first
  Serial    uart(PA_9, PA_10, 115200);
  //USBSerial usbSerial(0x1f00, 0x2012, 0x0001,  false); 
  USBTerminal usbSerial(0x1f00, 0x2012, 0x0001,  false);
  term = &usbSerial;  
}

main.cpp

USB對(duì)于時(shí)鐘是非常敏感的,所以必須在系統(tǒng)時(shí)鐘配置正確后才能夠產(chǎn)生USB對(duì)象。

在Mbed C++中,在調(diào)用main函數(shù)之前,進(jìn)行時(shí)鐘配置和對(duì)象實(shí)例化。RCC時(shí)鐘配置隱藏在Mbed Library中,如果對(duì)象在Main函數(shù)之外,視為公有對(duì)象,也在main函數(shù)之前進(jìn)行實(shí)例化。

如果將USB對(duì)象作為公有對(duì)象,F(xiàn)407工作正常,而F103工作不正常,表現(xiàn)在枚舉失敗。換而言之,在F407代碼中,可以將USBSerial/USBTerminal在main函數(shù)之外聲明,且工作正常。但是F103代碼中,同樣的代碼,編譯通過(guò),但是枚舉失敗。

所以第三方開(kāi)發(fā)者打了一個(gè)補(bǔ)丁,在main函數(shù)中增加了一個(gè)confSysClock()。有興趣的話(huà),可以查看RCC寄存器的數(shù)值。

由于時(shí)鐘是main函數(shù)中調(diào)用的,間接造成USB對(duì)象(USBSerial及其子類(lèi)USBTerminal)是main函數(shù)中的對(duì)象,其他模塊和函數(shù)無(wú)法訪問(wèn)。

解決方法是在main.cpp中預(yù)留一個(gè)USB對(duì)象指針,讓其他函數(shù)和其他模塊可以訪問(wèn)到USB對(duì)象。代價(jià)是USB對(duì)象的所有方法必須采用“->”來(lái)訪問(wèn)。這也就導(dǎo)致了基于Serial對(duì)象和USB對(duì)象的代碼存在兩套,這實(shí)在違背了OOP的原則。

由此看來(lái),基于Serial對(duì)象,基于F103的USBSerial,基于F407的USBSerial的通道,居然出現(xiàn)了兩套(確切地說(shuō)是2.5套)代碼。這種情況可能同樣會(huì)影響到其他協(xié)議,包括HCI/SIP/TLV/JSON等。

對(duì)于ARM來(lái)說(shuō),USB不是IoT的一部分。他們的IoT/Connectivity主要包括的是Cellular Modem/WiFi/BLE/LoRaWAN/BLE/TLS/MQTT等。

要合并代碼,還需要開(kāi)發(fā)者自己動(dòng)手。要么統(tǒng)一為指針類(lèi)型;要么期待Mbed底層得到修改。然而這些代碼都是基于Mbed 2,而Mbed 5并沒(méi)有對(duì)USB堆棧進(jìn)行維護(hù)。需要開(kāi)發(fā)者自己Backport。代碼在此:ARM Mbed OS STM32F103的系統(tǒng)時(shí)鐘配置代碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 盡管javascript里有大量?jī)?nèi)建引用對(duì)象,很可能你還說(shuō)會(huì)頻繁創(chuàng)建自己的對(duì)象。當(dāng)你在這么做的時(shí)候,記得javas...
    WanLum閱讀 597評(píng)論 1 3
  • 程序員創(chuàng)業(yè)白皮書(shū) 作者:Paul Graham Paul Graham是程序員,專(zhuān)欄作家。他在1995年創(chuàng)建了第一...
    劉立山John閱讀 2,138評(píng)論 0 20
  • 自然衝擊療法由丁愚仁老師發(fā)明,又稱(chēng)「禪拍」,「拍打」,"自然拍打"。 丁師及其團(tuán)隊(duì)總結(jié)經(jīng)驗(yàn),不同的各種病癥(含絕癥...
    YouAreMyMusic閱讀 2,664評(píng)論 0 4
  • 《達(dá)爾文所未知的》解說(shuō)詞 撰寫(xiě)(Written):阿爾芒·馬裏耶(The Animal Mother) 翻譯(Tr...
    JENTSON閱讀 1,620評(píng)論 0 1
  • 我喜歡你 盡管你是個(gè)好女孩 你不抽煙你不喝酒 你溫柔你漂亮 你顛覆了我,一切喜歡人的標(biāo)準(zhǔn) 可這樣,我還是喜歡你
    yukhaCHAN閱讀 115評(píng)論 0 0

友情鏈接更多精彩內(nèi)容