OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3139|回复: 9

用C++写单片机程序 STM32F103 + 自建固件库 + FreeRTOS 用gcc编译器和newlib(1篇)

[复制链接]

1

主题

2

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2019-5-22
在线时间
24 小时
发表于 2019-8-17 18:17:03 | 显示全部楼层 |阅读模式
      作为论坛的新人,先自我介绍一下。本人有10年的Win平台开发经验,从VS6.0一直用到VS2019,主要使用C#构建程序。在安徽某大学任教C语言程序设计7年,C语言自然是滚花烂熟。由于工作需要或者说是个人爱好,转战单片机。刚开始学习也是51+Keil用C语言开发,既然是学习实现的功能并不复杂,编写的代码量也不大,但还是体会到什么是一夜回到解放前。Keil的代码自动完成功能太弱鸡,如果做正式的项目效率会非常低。当时也只是想想而已,因为知道自己并不会去做实际的项目。之后当然就是学习STM32了,选择STM32主要是看中了中文资料多,学习人数多学习氛围好。STM32十足让我惊叹,比51复杂N倍的体系架构,超多的片上外设,还有如此低廉的价格。深入学习后发现还是Keil+C语言,至少市面上99%的学习都是基于这一框架的。非常的失望,非常的不适应。因为之前用C#开发Win应用,肯定是面向对象的开发思路,因为.NET Framework(相当于STM32的固件库)就是OO(面相对象)设计的,这么多年用下来,也深深的体会到OO的优势。不光是程序设计思路,还有就是IDE(集成开发环境)对开发者的重要性。我独自开发的Win应用最大的有10万行代码,我可以很轻松的构建,还能很轻松的完成代码维护,这里的代码维护指的是修订BUG,优化功能,增加功能,版本迭代等等。

      STM32F103的主频已有72MHz,复杂的系统架构,超多的片上外设。想要喂饱这个MCU或者说是发挥出它强大的功能,肯定是需要大量代码的。当代码数量达到一定规模,自然要面对代码结构的问题。用Keil+C可以做,完成需要的功能肯定没有问题,而且现在绝大多数人都在这么做。但是C语言是面相过程的语言,对代码结构毫无帮助,毫无益处,因为无计可施。达到一定规模后,代码逻辑估计只有设计者很清楚,别人要想看懂是一件很耗费时间的事情。导致这一结果的原因是有大量的宏,更可怕的是宏嵌套、使用全局变量,这个变量会被多少函数共享,在什么时候会被改变分析起来很头疼、大量的函数,这些函数在语言层面是相互独立的,但逻辑上可能是有联系的,在语言级并没有这种逻辑关系的表达。就像官方的HAL库,我读起来想死的心都有。不是我读不懂而是读懂这些我付出的时间代价太大,要在OO思路下,这个要轻松N倍。时间就是金钱,效率就是生命。官方的HAL库其实就是想实现一个硬件抽象层,让开发者对于不同型号的MCU有一个统一的应用层开发界面,提高代码的移植性,缩短开发周期。想法是好的,做法是失败的,因为HAL库还是再用C语言编写,硬是用C语言套OO思路,代码恶心到极致。这也就是STD库还是有人在用的原因。如果使用真OO就可以把逻辑上有关联的函数组织到一起,将一些全局变量限定在部分函数中共享,其实这就OO中的封装,是语言层面提供的支持。还有要吐槽的地方就是IDE,VS的代码自动完成功能真的很好用,只要你按下任何按键都会出现提示列表,按下空格自动填充你还没有输入的内容,还有参数列表的提示。带来的好处就是,我不需要记住所有函数的名称和参数列表,我只要有一个模糊的映像,输入代码的时候IDE协助我完成。让我专注于逻辑思路,代码只是完成逻辑思路的工具而已。对语言再熟悉,对函数再熟悉,没有一个好的逻辑思路仍然写不出优秀的应用。不光是代码自动完成,还有代码着色,代码折叠,代码重构等等IDE功能,对于开发真的是不可或缺。Keil可能也有这方面的支持,但和其它一些IDE相比真的太弱了。再次重申一遍,时间就是金钱,效率就是生命。Keil+C可以吐槽的地方还有很多很多,我可以给你说一整天,我并不想开吐槽大会,只是想告诉大家其实可以有更好的选择。

     说一下代码效率问题,这可能是大家非常关注的地方。绝大多数人会认为C++的时间效率不如C,但是你要知道C++是C的超集,使用C++开发并不是什么地方都必须C++,你任然可以写C函数,任然可以写嵌入汇编代码。C++的效率损失主要是函数调用,C语言中会将参数压栈,而C++对象函数除了压栈参数以外还要压栈一个this指针,多一个32位的变量而已。表面上看是多了一个参数,但事实上呢?C语言函数可能需要4个参数,而对象函数的这个this指针却能代表这4个参数,因为C++通过这个this指针去访问私有变量,而这些私有变量恰恰是C函数的那4个参数。以上的说明可能过于抽象,你现在未必需要知道细节,你只要明白一点,效率的损失不是绝对的,有时却是一种效率的提升。再高级一点的效率损失来自于多态。在C99里面已有函数参数的多态支持,即使相同函数名但参数不同,调用时根据给定参数自动选择对应的函数。这种多态在C++里面也是存在的,但这种多态是在编译时完成的,对运行效率毫无影响。而虚函数多态的效率损失才是重点,当使用基类指针指向一个子类并调用虚函数,实际运行的时候会确定实际对象的类型去调用不同版本的虚函数,这需要在运行时查找虚函数表来完成,多了一个查找的过程,在内存中多了一份虚函数表。但是这种特性有助于实现一个优秀的代码结构或设计思路,用纯C可能实现不了或者实现了效率也未必比C++来的高效,而代码的逻辑和结构肯定没有C++的优雅,构建的速度也没有C++来的快。对于虚函数的采用是选择性的,没有什么项目在任何位置都需要虚函数。而一些普通的代码,例如:int a, b; a = 10; b = a + 200; if、for......不管是用C还是C++生成的汇编代码都是一致的。第二是空间效率,上面也分析了时间效率,所以空间效率可能有所损失,但也不是绝对的。当你用到一些特性的时候,执行的代码量必然增加,所以固件的体积肯定会有所增加。C++还有个STL库,里面实现了很多基础类,这些基础类可以直接使用或者进行再封装。当你使用这个库时,固件体积会极速增加。对于一些Flash只有64K或更小的MCU,可能有点紧张。但对于更大容量的Flash完全就不是问题了。使用这个库的好处就是,更少的BUG,更快的构建速度。这也是选择性的,你可以根据实际情况自由选择。而C语言中的常用库,例如printf、abs、floor等在C++中也是可以用的,且不会因为你是C++这些库函数就发生变化。总结起来就是可能会带来一些效率的损失,这些损失大部分是选择性的,当你选择牺牲性能的同时会得到C语言无法实现的功能,得到优雅的代码,得到清晰的逻辑,得到快速的构建。对于当今的MCU性能的损失往往都是可以接受的,你能不能喂饱单片机反而是个问题。当你在C++中需要极致性能的时候,你任然可以像C语言一样,该干嘛干嘛。

      互联网上可以找到的资料实在是少之又少,断断续续搞了2年,现在已经完整构建了整个环境,打算写一个连载。这是第一篇,主要是阐述这种开发环境的优势。后面将陆续给大家分享开发环境的搭建,为什么要自建固件库,如何自建固件库,FreeRTOS如何与C++联合使用,newlib中如何实现printf重定向到串口,以及在实践过程中遇到的各种零碎的问题。随着芯片科技的不断进步,MCU性能的进一步加强,我相信这种环境将是未来的主流。也希望一些技术大牛不要再保守秘密了,把真正的技术都分享出来,彻底提升MCU编程。目前我已在用这个环境做实际的项目了,下面给一张开发环境的截图。
IED.jpg

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2019-7-4
在线时间
3 小时
发表于 2019-8-18 12:08:57 | 显示全部楼层
回复 支持 反对

使用道具 举报

0

主题

32

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
268
金钱
268
注册时间
2018-12-2
在线时间
76 小时
发表于 2019-8-18 21:39:57 | 显示全部楼层
真大神系列,前来膜拜
回复 支持 反对

使用道具 举报

5

主题

72

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2018-1-14
在线时间
26 小时
发表于 2019-8-23 02:32:40 来自手机 | 显示全部楼层
坐等出帖!
回复 支持 反对

使用道具 举报

42

主题

95

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
456
金钱
456
注册时间
2017-9-8
在线时间
58 小时
发表于 2019-10-16 21:01:30 | 显示全部楼层
蹲大大大大大大大
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2019-9-10
在线时间
6 小时
发表于 2019-10-16 23:41:44 | 显示全部楼层
真大神,前来膜拜
回复 支持 反对

使用道具 举报

27

主题

195

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
232
金钱
232
注册时间
2016-8-31
在线时间
252 小时
发表于 2019-10-17 10:24:58 | 显示全部楼层
顶!!!早就想这么干了好好跟楼主学学
回复 支持 反对

使用道具 举报

19

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
481
金钱
481
注册时间
2016-6-2
在线时间
116 小时
发表于 2019-10-30 08:45:03 | 显示全部楼层
请问楼主,使用cubemx自带的FREERTOS,加上GCC编译之后freertos的文件报错,怎么处理?
d:\Pictures\微信截图_20191030084322.png
回复 支持 反对

使用道具 举报

19

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
481
金钱
481
注册时间
2016-6-2
在线时间
116 小时
发表于 2019-10-30 08:49:18 | 显示全部楼层
怕图片传不上去发个文字版的
../Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c(235): error:  #513: a value of type "void *" cannot be assigned to an entity of type "BlockLink_t *"

../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c(934): error:  #513: a value of type "void *" cannot be assigned to an entity of type "osPoolId"
../Middlewares/Third_Party/FreeRTOS/Source/tasks.c(2806): error:  #513: a value of type "void *" cannot be assigned to an entity of type "TCB_t *"

使用正确的类型转换之后,没有报错了,但是一运行就卡在中断服务函数‘SVC_Handler’
出错的地方也找到了,
  1. __asm void vPortSVCHandler( void )
  2. {
  3.         PRESERVE8

  4.         ldr        r3, =pxCurrentTCB        /* Restore the context. */
  5.         ldr r1, [r3]                        /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
  6.         ldr r0, [r1]                        /* The first item in pxCurrentTCB is the task top of stack. */
  7.         ldmia r0!, {r4-r11}                /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
  8.         msr psp, r0                                /* Restore the task stack pointer. */
  9.         isb
  10.         mov r0, #0
  11.         msr        basepri, r0
  12.         orr r14, #0xd
  13.         bx r14
  14. }
复制代码

请问您有遇到同样的问题吗?有没有什么解决办法啊?
回复 支持 反对

使用道具 举报

1

主题

2

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2019-5-22
在线时间
24 小时
 楼主| 发表于 2020-2-3 05:37:52 | 显示全部楼层
顾影_ 发表于 2019-10-30 08:49
怕图片传不上去发个文字版的
../Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c(235 ...

没有,应该可以解决
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-20 03:47

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表