STM32F1 F4 USB 工程更新

现状

  • 基于STM32CubeMX的F103/F40X的USB堆栈测试完毕;
  • 基于Mbed OS的F103/F40X的USB堆栈测试完毕;
  • 主要测试USB CDC设备;
  • 基于USB ACM/CDC实现nRF24L01及类似“小无线”系统集成;
  • 基于USB ACM/CDC开发了VT100 cmdline
  • 基于USB ACM/CDC和cmdline实现SPI NOR Flash的读写;
  • 基于USB ACM/CDC开发HCI定制协议;
  • 基于Linux udev的USB设备插入拔出时间的检测;

计划

  • 开发其他TLV类型二进制协议和基于字符串的JSON RPC等协议;
  • 实现xmodem传输;
  • 实现I2C设备扫描与访问;
  • 更新现有的LoRaPHY/Aloha/LoRaWAN USB Dongle;
  • 支持C8T6/RCT6等多种核心板,以应对更加复杂的堆栈;
  • 支持USB ECM,以直接支持6LowPAN等物联网设备;
  • 集成Arduino STM32的Bootloader实现固件升级。

开源设计与板级产品

  • 大部分设计都是开源设计;
  • 或有根据客户要求定制进行设计;

代码设计过程

以下内容针对Mbed C++和STM32F103/F407

今天完成的主要是在USB通道上实现VT100 cmdline,可以通过TeraTerm终端来配置管理设备,或者通过专门的cmd/GUI上位机程序实现自动化配置。最早基于C和串口,在Mbed Serial类上移植也很容易。但是在USB信道上实现cmdline很花费了一些时间,且有了反复。主要原因是USB对象初始化的特殊性,以及Mbed C++与基于标准库或HAL库的原始设计的差异所造成的。

基于标准库或者HAL库的模板一般是:

  • 将所需硬件资源(串口、GPIO)声明为main的全局变量
  • 将USB声明为 extern 全局变量
  • 在主函数中配置时钟,初始化这些硬件资源
  • 展开应用逻辑

发现STM32 CubeMX的USB实例是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对于时钟是非常敏感的,所以必须在系统时钟配置正确后才能够产生USB对象。

在Mbed C++中,在调用main函数之前,进行时钟配置和对象实例化。RCC时钟配置隐藏在Mbed Library中,如果对象在Main函数之外,视为公有对象,也在main函数之前进行实例化。

如果将USB对象作为公有对象,F407工作正常,而F103工作不正常,表现在枚举失败。换而言之,在F407代码中,可以将USBSerial/USBTerminal在main函数之外声明,且工作正常。但是F103代码中,同样的代码,编译通过,但是枚举失败。

所以第三方开发者打了一个补丁,在main函数中增加了一个confSysClock()。有兴趣的话,可以查看RCC寄存器的数值。

由于时钟是main函数中调用的,间接造成USB对象(USBSerial及其子类USBTerminal)是main函数中的对象,其他模块和函数无法访问。

解决方法是在main.cpp中预留一个USB对象指针,让其他函数和其他模块可以访问到USB对象。代价是USB对象的所有方法必须采用“->”来访问。这也就导致了基于Serial对象和USB对象的代码存在两套,这实在违背了OOP的原则。

由此看来,基于Serial对象,基于F103的USBSerial,基于F407的USBSerial的通道,居然出现了两套(确切地说是2.5套)代码。这种情况可能同样会影响到其他协议,包括HCI/SIP/TLV/JSON等。

对于ARM来说,USB不是IoT的一部分。他们的IoT/Connectivity主要包括的是Cellular Modem/WiFi/BLE/LoRaWAN/BLE/TLS/MQTT等。

要合并代码,还需要开发者自己动手。要么统一为指针类型;要么期待Mbed底层得到修改。然而这些代码都是基于Mbed 2,而Mbed 5并没有对USB堆栈进行维护。需要开发者自己Backport。代码在此:ARM Mbed OS STM32F103的系统时钟配置代码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,290评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,107评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,872评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,415评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,453评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,784评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,927评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,691评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,137评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,472评论 2 326
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,622评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,289评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,887评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,741评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,316评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,490评论 2 348

推荐阅读更多精彩内容

  • 尽管javascript里有大量内建引用对象,很可能你还说会频繁创建自己的对象。当你在这么做的时候,记得javas...
    WanLum阅读 527评论 1 3
  • 程序員創業白皮書 作者:Paul Graham Paul Graham是程序員,專欄作家。他在1995年創建了第一...
    刘立山John阅读 1,881评论 0 20
  • 自然衝擊療法由丁愚仁老師發明,又稱「禪拍」,「拍打」,"自然拍打"。 丁師及其團隊總結經驗,不同的各種病症(含絕症...
    YouAreMyMusic阅读 2,247评论 0 4
  • 《達爾文所未知的》解說詞 撰寫(Written):阿爾芒·馬裏耶(The Animal Mother) 翻譯(Tr...
    JENTSON阅读 1,331评论 0 1
  • 我喜欢你 尽管你是个好女孩 你不抽烟你不喝酒 你温柔你漂亮 你颠覆了我,一切喜欢人的标准 可这样,我还是喜欢你
    yukhaCHAN阅读 92评论 0 0