忙完一天的工作回家,随手打开了CSDN APP,就看到APP推送了一些有关嵌入式成长发育路线的博客文章,于是好奇点进去看了看,有很多是在校大学生朋友写的博客,有写先学51,再学STM32,最后学ARM LIUNX,并列举了一些关键知识点,写得也都很用心,感叹自己在读书的时候可能还没有这么高的觉悟,仿佛只会各个版本的按键点灯。
这篇博客的篇幅不会很长,在此感谢大家的阅读,希望它可以给朋友们带来一些收获,启发,亦或者产生一些共鸣吧!
先谈谈FPGA吧,初学的朋友们,可能会有很多各种各样的疑惑,比如怎么才能在较短的时间内掌握这门技术并应用在现实项目工程中,应该先去学什么后去学什么,看到市面各种学习教程都说法不一怎么办;是不是写任何一个模块都必需要代入Modelsim仿真验证,但在写Testbench的时候没有思路怎么办;怎么样才算是书写整洁的代码架构,参加各类培训机构都会或多或少地刻意宣传自己的代码规范,但培训完后到头来感觉还是收获甚微怎么办;模块划分以后再具体编程各个功能模块的时候,却没有整体代码规划怎么办;在工作当中遇到一些棘手的问题很难去定位原因怎么办,接手了一份前人神仙般的代码是坚持if else、flag般的小修小改,还是说服自己去推倒重构。
其实在刚接触一门技术,或者刚步入工作岗位不久都会带有类似的这些困惑,但谁也没有灵丹妙药,只能说多练习、多思考、多总结。学习任何一门新技术,学习的过程基本都是先接触、再熟悉、后模仿、最终在实践当中灵活运用实现二次创造,所以很多时候需要静下心来去思考一些细枝末节,多看多练,核心关键技术也就慢慢掌握了。
抛开技术实现上的细枝末节,在拿到一个项目需求的时候可以给自己一点时间先来思考以下几个问题:1.数据从哪里产生的;2.数据是如何流向的;3.数据要怎样缓存的;4.数据做什么处理的,大家不妨可以在动手编码之前试着想想这些问题,有趣的是当我们需要完成的功能越加复杂,就越多去思考这些问题,搞清楚上面四个问题,相信之前很多的不解也就自然烟消云散了。
对于FPGA设计,数据可以从很多地方产生,典型的有从各种外设高速接口处收到数据、从不同通信协议总线上得到数据、从少数存储采集芯片里读到数据,而这里显然需要去编写一些代码模块完成对这些数据的接收工作;接着有了数据,就需要考虑这些数据应该怎么去流向呢,即通俗地说收到的数据我们应该用到哪里,当然根据不同的需求又有不同的设计,很难概括性几句话描述得很清楚,需要大家多在项目工程中积累一些设计思路和设计技巧,勤学勤练很快就可以举一反三;其次数据在各个模块之间进行交互,就需要考虑到数据的缓存问题,因为各个模块之间的处理速度是不同的,这就涉及到前面我们所练习到的FIFO和RAM两个经典IP核了,需要针对不同应用场景做不同的代码设计,甚至对于大批量的数据缓存需要借用外接的ddr3内存颗粒;最后核心内容也就是数据处理了,涉及到方方面面同时也是最难处理的部分,在这里可能存在具体算法或者运算操作要借用FPGA的并行性加以实施,典型的有FFT快速傅里叶变化,图像CNN卷积运算等等。其实上面这四个问题,完全可以抽象看成FPGA项目开发的一个整体浓缩概括,也是笔者在实际项目研发中逐渐总结来的。
在搞清楚整个设计的大框架,清晰了模块划分原则,并积累了一定的代码量和开发调试经验后其实已经有了研发能力,但研发路上总会有很多新问题,新事情,导致一些朋友对新的事物会感到畏惧,害怕能力无法胜任、短期难以掌握等等,其实有时候自信一点比啥都好,就好像上学考试的时候,复习再多最后肯定还会有没见过的题型,但来来回回都是那些知识点的排列组合,今天写了UART,明天遇到IIC、SPI一样分析搞定,今天用了SFP,明天用到PCIE、SATA多看看官方手册等资料只是模块划分在变化,涉及到底层的状态机和计数器在改变,大的没有变,小的一直变,但搞研发就要不断学习,及时更新知识背景。
再谈谈ARM,关于ARM LIUNX,只能说自己还刚把网课刷完一轮实践了下,所以这里先不做过多总结吧,暂时就说说STM32吧。
STM32应该怎么学,或者掌握到什么程度才能达到高薪要求,上学的时候大家都会有这样的疑问,可惜的是学校不会给出答案,花费很多金钱报名培训好像能让快速入门上手,但正真遇到工作中棘手的问题还是一筹莫展。
其实和FPGA设计一样的道理,一份漂亮代码的时序逻辑永远是设计出来的,各个模块之间交互很好,STM32是单片机,说到底是将写的C语言编译成汇编一条条运行,但往往STM32开发又涉及到通信,存储,界面,控制等现实需求,所以有经验的工程师,就会做好各个层之间的分割,哪些事情交给驱动层,哪些事情交给逻辑层,哪些事情交给应用层。
比如对于通信不管SPI、RS232、RS485,都通过DMA和空闲中断的方式把发来的数据整包收到,一包数据接收完触发一次中断,对于裸机来说中断里置位flag,在main的while(1)里处理各种中断产生的flag即可,对于系统来说中断里直接把报文扔给消息队列,时间片轮转到了对应的任务集再取出消息队列的报文做进一步处理即可,这样就极大地优化了底层,减少了频繁进中断给MCU带来的工作压力,保证了程序的稳定性;对于存储来说,有时候需要存储一些数据或者图片,可以考虑到EEPROM,内部FLASH和外部FLASH等,对于小数据量几个字节的EEPROM是首选,当然为了节约成本也可以存到内部FLASH里,一般把图片的大数据量的存到外部FLASH里;对于界面可以用主流的EMWIN人机界面,也可以人为绘制界面等等,注意刷屏操作例如在EMWIN里开300-500ms的定时器不断刷新报文给来的新数据,整机显示的实时性就可以做到很好;对于控制典型的有ADC采集,DAC控制,电机控制,PID调节等等,具体需求具体分析即可,这些会在后面博客里通过具体项目工程分析。
做到这些后积累了一定的项目经验和代码量,可以抽空再把Freertos研究研究,一些常用的库自己动手移植应用下,学有余力掌握一些周边的通信协议栈,如Zigbee,蓝牙,Wifi等等,丰富自己的知识面。