最近使用STM32F103RBT6设计了一个小产品,在此分享一下设计中的心得体会;5 D7 x k- Q$ U/ ]. { 1. 芯片选型 最初仅着够用和可扩展的思路,及需要3个UART,选择了64PIN的芯片STM32F103R8T6;在华强北买样片时,发现RB的芯片价格差不多,而FLASH容量达到128KB;所以第一版硬件选择了STM32F103RBT6,芯片20KB RAM, 128KB FLASH。做到后面升级功能时,需要加上RSA签名校验,RSA使用1024bits密钥的话需要6KB左右的STACK,一个RSA KEY变量就是4KB左右,所以20KB的内存基本上干不了其他什么活了。 最终选择了STM32F105RBT6, 64KB RAM, 跑个RSA 2048bits都足够用了。又在华强北买芯片时,老板说STM103RB芯片涨价到15块钱, 而STM32F105RB可以卖到9块,批量更低,有点瞎猫碰到死耗子的感觉,呵呵。 从103换到105时,PIN2PIN是兼容的,但以下两点需要注意:) |, G- ^4 G7 R, D% ` a. F103使用内部8MHz RC振荡器,可以倍频到64MHz工作;但F105使用RC振荡器倍频上不去,如果使用外部晶振,可以倍频到72MHz,我的产品涉及到UART通信,接了外部晶振,所以不是问题;开始使用RC倍频到36Mhz,RSA签名验证需要0.5秒。结合RAM占用需要10KB,需要的同行可以此作为RSA移植参考。4 o, D$ F3 c) n ^ b. FLASH的block大小不同,F103是1KB block, 而F105是2KB block。在FLASH上保存设置参数,或涉及分区时,要注意区别。$ G6 P9 ]; d* Q1 L! Y% Z* h d, K/ z9 W: |4 b 2. 开发生产工具选择8 A6 Y ^: G2 A& k a. 采用STM32CubeMX生成驱动代码;跟随ST主流,接受新东西,减少重复制造轮子。5 _( D: K, w5 }/ W! W" s# l 我的产品中对驱动生成代码的唯一修改是,在UART的接收函数中,将中断程序接收到的数据直接扔进一个环形buffer;原来的接收函数评估收发可以,做产品真不好用。3 ?/ E r6 h7 Q( M. ` b. 采用Atollic TrueSTUDIO for ARM 7.1.2开发环境 STM32CubeMX可以直接生成这个软件的工程;最早使用过EMIDE, EMBLOCK,说实话都不好用。 c. 使用STLINK,而不是JLINK {. k; q& K% N/ n! c, F- C; ^0 s 硬件接口只拉了SWD的4条信号线(VCC/GND/SWDCLK/SWDIO),用JLINK及其不稳定。用ST很稳定。 d. 烧录使用STM32 ST-LINK Utility 这个工具最方便的地方在于,可以在控制台脚本中调用。在cygwin脚本中,用法如下: STLINK="/cygdrive/c/Program Files/STMicroelectronics/STM32 ST-LINK Utility/ST-LINK Utility/ST-LINK_CLI.exe"$ L$ P' J6 r V + d( M9 ~3 m$ T0 t8 e + R# P6 u" w3 d4 y1 c$ Z3 q# x "$STLINK" -V -P factory.bin 0x0801F800 // FACTORY$ _, X( y" |) l. ^4 `3 L& B% N 使用该工具,可以实现生产自动化。但速度不是很快,可能只适合小批量的生产。# L/ s$ e3 ]8 \/ V; z! \ e. 升级使用Flash Loader Demo 在硬件上预留了跳线,可以强制进入UART1的程序刷新; 适用于客户现场没有stlink,通过串口强制更新程序。 f. 在线升级 由于我的产品就是个3G的DTU模块, 客户那边流量也不是问题, 所以我设计了一套在线升级的功能。 PC软件只能自己定制设计了,MCU侧,先下载缓存升级包,然后进入BOOTLOADER,验证设计包完整后, 将缓存数据刷新到程序运行区域。: _: n/ r$ ^: d 在此为Cortex M3灵活的中断向量映射方法点赞!+ }3 }* [* i4 e7 M# {$ D1 n |
【管管推荐】STM32经验分享篇
STM32固件库分享,超全系列整理
小马哥STM32F103开源小四轴RoboFly全部资料大放送
【MCU实战经验】+STM32F107的USB使用
基于STM32F103两轮平衡小车设计(开源)
STM32F107VCT6官方原理图和PCB
【福利】用STM32库的朋友有福了:STM32F10x_StdPeriph_Lib_V3.5.0chm...
基于STM32F10xx存储器和系统架构经验分享
基于STM32F1的CAN通信之BH1750
基于STM32F1的CAN通信之OLED
3. 防止解密的一些设计! a& t! C/ S- n, L' F6 r$ G/ u/ X
设计目标:防止解密者克隆芯片程序到其他芯片后,直接运行。
从目前了解的情况看,单机运行的程序是不能防止解密者反汇编破解的;又听说STM32芯片的芯片ID都已经可以被改写, FLASH读保护加密了也可以读出数据。基于这些信息, 我也只能做到为破解的人制造一点点的麻烦。主要采取了如下一些措施:$ ^0 P9 e4 \7 Y, C: |# B" @+ K
a. 读出3G模块的MEID或IMEI号,替代MCU的芯片ID。但该方法无法避免反汇编NOP等方法破解
b. 对MCU的芯片ID及其他配置信息进行签名,启动时进行验证;
c. 程序被分为BOOTLOADER/APP两部分,将一些控制功能分开放入这两个阶段中运行。以前需要破解一个程序,现在需要破解两个。
d.升级时,对升级包进行签名校验
e. 将一些控制逻辑,加密后放入3G模块当中。 MCU好破解,3G模块破解就没那么容易了。% A) q' `6 |$ {! `$ a% R
f. 白盒加解密算法将算法和密钥混合在一起, 是比较安全的。但没有找到合适的代码可以移植。 有懂得人麻烦提供一些信息,谢谢!3 X: M! P" d7 D/ s
作为方案公司,需要保护自己的劳动成果,采取这些措施,也就是防个君子,防不了小人。
7 e3 @/ B# D y) t) L) Y
4. 性能的调优
当前DTU的环回测试速度可以稳定跑在1KB/s, 但没有达到UART 115200bps的十分之一。可以优化的地方在于:
a. MCU与3G模块采用UART连接,但是baudrate采用115200*2 bps;
b. MCU与3G模块采用USB连接接,STM32F105的芯片USB应该可以做HOST
5. 功耗调优! y/ V" z# `2 R& k
TBD
a.AT命令错位:当前MCU与Modem通过AT命令交互,没有协议或规格要求一条AT命令必须在多长时间之内必须返回;AT命令超时时间设置短了,会导致重复多发AT命令,可能导致Modem命令执行中断或后续数据大量的返回,最终导致解析程序处理AT命令错位,或MCU不能获得Modem的正确状态;超时时间设置长了, 出了问题不能及时处理。这个参数与Modem/网络状态都有关系,需要根据实际情况调试确认。
b. Modem返回数据解析错位或丢失。通过压力测试可以发现/复现/解决,工作量的问题,但有时处理起来令人恼火,需要多一些耐心。
c. 资源总是有限的,尤其是RAM, 收发缓存RAM大小配置要合适;缓存越大越好。
p1 r: ^( H X
7. 可以拓展的空间$ t0 O. z) _7 F. E
现在的网络模块大都采用TCP协议连接,并且数据都是明码跑在网络上,如果在MCU中实现SSL/TLS,则可以实现身份鉴权/数据加密等功能。不过相应的芯片可能要采用STM32F4系列了,它们支持硬件RNG, AES,OTP, CRC。
8. 其他帮助我们提高效率的工具3 Z( `0 n0 H. o& v) W" w' U. q/ H7 `
a. beyondcompare
b. sourceinsight) I, B D' {; N/ O
c. snv/git" w7 `+ v, \2 ^+ v
d. cygwin/shell