笔者在嵌入式领域深耕6年,对嵌入式项目构建,BLDC电机控制,产品上位机开发以及产品量产和产品售后维护有多年工作经验。经验分享,从0到1, 让我带你从实际工作的角度走进嵌入式成长之路。
原创不易,欢迎大家关注我的微信公众号:嵌入式工程师成长之路 或 扫下面二维码
所有文章总目录:【电子工程师 qt工程师 做产品过程中遇到的坑】
原创视频总目录:【电子工程师 qt工程师 做产品过程中遇到的坑】
产品使用的是stm32f103rbt6作为主控芯片(其它主控也类似),有128KB的iROM和20KB的iRAM。
这里的iROM是nor flash(上电即可以使用,数据掉电不丢失),它是直接接在stm32地址总线上的,并且程序是运行在该flash上(可以通过配置,下载程序时是运行在flash上,还是运行在iRAM上)。
这里的iRAM是静态内存,静态内存是不用初始化的,上电即可使用,但掉电不能保持数据。iROM和iRAM都是芯片厂商集成在mcu内部的,如果程序大小超过128KB,可以外接一颗内存芯片,但会额外增加硬件成本。
文章【专题1:电子工程师】 之 【2.SoC/MCU常用外存和内存的部署问题】 有详细解释各种存储介质的特性。很多芯片的启动做的非常复杂,主要是因为这些存储介质本身的特性决定的,同时在设计时,还必须考虑系统成本。
为了节省成本,不外接任何存储介质,并且直接使用mcu内部高速时钟,这种配置对于99%的应用已经够用了。
整个系统由stm32_bootloader,stm32_app,上位机,微信小程序和服务器5部分组成(stm32_app是必须要的,其他的看产品的功能)。系统上电之后,先运行bootlaoder,bootloader对芯片进行校验以及对app进行校验,都校验通过之后,跳转到app中运行产品的业务逻辑。如果需要升级,再从app跳转到bootloader,对app的空间进行擦除以及写新的固件到里面。
① 更新stm32_app,iap升级。
② 对stm32_app进行校验。
③ 对芯片进行校验:硬件抄板是非常容易的,如果mcu里面的固件没有加密的话,3000元左右就可以在淘宝上叫人把flash里面的程序拷贝出来,这将给公司带来致命损失,所以固件必须加密。每一颗stm32芯片都有一个全球唯一的UID,我们可以通过UID和一段固定的算法对芯片进行加密,想要破解这种加密是非常困难的,几乎不可能。
④ 跳转到stm32_app中运行。
⑤ 和上位机进行通信。
① 产品真正的业务逻辑代码。
② 和上位机进行通信。
① 更新产品固件,通过上位机和stm32_bootloader,可以更新stm32_app,也就是做iap升级。
② 对产品的参数进行标定。
③ 产品的下线测试。
④ 产品的故障诊断,主要用于售后。
⑤ 对服务器的固件进行管理,譬如上传和下载。
⑥ 对最原始的bin文件进行加密。
① 存储产品固件,让产品可以通过微信小程序升级。
② 收集用户信息,给用户精准推荐商品。
③ 集成一个微信商城。
④ 收集终端用户的故障信息。
微信小程序是跨平台的,开发好之后可以直接Android和ios系统上的微信上运行,如果产品是国内市场,这是没有问题的。因为额外配备一个Android工程师和ios工程师,会给团队增加人员成本。
① 升级产品固件。
② 产品标定。
③ 故障诊断。
这个模块用于响应从数据接口过来的数据,譬如手机端或电脑端的输入,用于数据通信。
包含的第1个模块:fifo(负责数据的收发)
每一个操作硬件的函数最好是原子操作,譬如转动电机,分为三步,启动电机,设置速度,停止电机
分为三层:
业务逻辑层:譬如转动电机,它通过组合式的调用硬件代理层的接口实现具体的操作
硬件代理层:主要是为了做到业务逻辑代码和硬件操作的隔离,类似于接口的作用
硬件平台层:具体的操作硬件的接口,和平台有关
将整个系统化为为多个模块,譬如led模块,led的不同闪烁频率或节奏表示系统处于不同的工作状态;电机模块。
如果这个模块有数据结构,需要专门保存在模块的对应结构体中。
这是一个物体的高度抽象体,譬如产品是一个自行车,那么产品模块就是一个自行车,里面包含了多个module模块。由于module可裁剪或替换,譬如是否有油门,使用什么品牌的力矩传感器,这些module的有无,产品的运行效果就不一样了。譬如把所有module模块都加入到系统中(缺点:需要更大的flash),通过上位机来标定具体需要运行哪些模块,不同module的有无,会使产品的运行效果不一样。
需要权衡加入操作系统是使软件开发更简单了,还是更复杂了。
总结:
设计原则,大模块里面包含小模块的指针,在大模块的构造函数中将小模块对象的指针传入。
关于是否引入操作系统:操作系统的调度很简单,比较复杂的是各个任务之间的通信以及任务之间优先级配合的问题,这些问题处理不好,很容易给自己挖坑,我们这个通用框架就先不引入操作系统。但我们还是构建一个单线程的,同样也具有调度模块的软件。在绝大多数产品都可以使用这套框架。
Mcu一共128KB flash 20KB iRAM。
(1)stm32_bootloader: 0x8000000 - 0x8005800: 22k
(2)密钥地址: 0x80057E0,用于存放芯片密钥。
(3)mcu_app: 0x8005800 - … 0x801D000 : 94k
(4)common data: 0x801D000 - 0x8020000: 12k
801D000 - 801D800 2K 系统信息
801D800 - 801E000 2K 工程师和制造商系数
801E000 - 801F000 4K 用户参数(E2PROM)
801F000 - 8020000 4K 其他信息(E2PROM)