[STM32F4] [STM32F413]一个F413上的简单的C++程序例子

[复制链接]
3716|11
 楼主| zhanzr21 发表于 2017-1-21 12:11 | 显示全部楼层 |阅读模式
本帖最后由 zhanzr21 于 2017-2-5 19:57 编辑

发个简单的C++程序,F413上跑.
Cortex M核上跑C++一直有些争议性, 其实本人认为随着硬件速度提高,RAM空间慢慢扩展, 应该有越来越多的程序使用C++开发.
使用C++开发相比C语言比,有以下优缺点:
优点:
1.C++的算法,容器类非常丰富
2.其他平台上有很多C++的代码库可以更方便移植
3.嵌入式编程其实更适合面向对象编程的模型,比如一个按键, 一个LED, 一个Flash都可以看作对象

缺点:
1.目前还只适合有一定运算性能和SRAM的MCU, 比如STM32F40x及以上, 因为C++的开销还是有点大,相对于几十M的频率, 几十K的SRAM来讲
2.目前工具支持还不够,编译器连接器都是走前面,但是IDE等工具比较落后, 比如CubeMX不支持输出C++代码,HAL, SPL, LL, USB, 等库函数都是C风格的
3.用C++开发就是你自己前行了,遇到问题就没有那么多人帮你解决了,因为目前嵌入式领域还是C程序员占绝大多数

虽然有上面这些问题. 但是并不妨碍现在就开始了解一下这方面的知识.

看看这个例子的代码:
1.加几个包含, C++跟C的一个显著差别:用到的程序必须申明,不能到连接时候才去找,这一点可能有点让C程序员感到麻烦, 其实是为了让程序更严谨,降低后面出问题的概率
  1. #include <cstdint>
  2. #include <cstring>
  3. #include <cstdio>

  4. #include <algorithm>
  5. #include <vector>
  6. #include <numeric>

  7. #include <stdlib.h>
2.声明一个vector, 理论上这个vector刚开始没有内容,但是还是要占一点空间, 至于占多少,跟编译器的实现有关
  1.         std::vector<uint32_t> vD;        
3.生成10个随机数,push_back进到刚刚那个vector中去, 第一个元素加进去的时,这个vector的capacity就增加到32, 这个32也是由编译器的实现决定的,如果是电脑上的编译器,一般是500, 1000这样.
  1. vD.clear();
  2.                 printf("generate 10 rand number and push to the vector:\n");               
  3.                 for(i=0; i<10; ++i)
  4.                 {
  5.             vD.push_back((uint16_t)rand());
  6.             printf("%u ", vD.at(i));
  7.                 }
这里没有用iostream中的输出std::cout,是因为我这个重定向用了ITM, 跟Keil Runtime 有点冲突, 暂时没有找到解决办法, 后面找到了再来更新, 暂时先用printf顶住.
4.使用algorithm与numeric中的库调用:sort与accumulate, 排序, 累加 ,这里看出C++的好处,写复杂程序的时候, 这一点尤其突出
  1. printf("\nNow sort them and the result:\n");
  2.                         
  3.                 std::sort(vD.begin(), vD.end());
  4.                
  5.                 for(i=0; i<10; ++i)
  6.                 {
  7.                         printf("%u ", vD.at(i));                        
  8.                 }
  9.                
  10.                 printf("\nsum: %u, capacity:%u\n", std::accumulate(vD.begin(), vD.end(), 0), vD.capacity());                        
工程文件在附件中, 目前来说使用C++的话, 首先要把硬件配置好, 因为一旦开始用C++编程, 跟CubeMX的同步关系也结束了.

还有一个要提出的是, ARM CC对C++11的支持也越来越完善了. 会在以后的帖子中谈到.
这里是ARM官方关于C++11的说明, 感兴趣的可以看看: http://www.keil.com/support/man/docs/armcc/armcc_chr1407404265784.htm
附件: F413_CPP_Test.zip (1018.36 KB, 下载次数: 43)

补充: 研究了一下, iostream可以用了, 参考了ARM公司的说明:
Redefining low-level library functions to enable direct use of high-level library functions in the C library关键代码:
  1. #include <stdio.h>
  2. namespace std {
  3.   struct __FILE
  4.   {
  5.     int handle;
  6.     /* Whatever you require here. If the only file you are using is */
  7.     /* standard output using printf() for debugging, no file handling */
  8.     /* is required. */
  9.   };
  10.   FILE __stdout;
  11.   FILE __stdin;
  12.   FILE __stderr;
  13.   int fgetc(FILE *f)
  14.   {
  15.     /* Your implementation of fgetc(). */
  16.     return 0;
  17.   }
  18.   int fputc(int c, FILE *stream)
  19.   {
  20.     /* Your implementation of fputc(). */
  21.   }
  22.   int ferror(FILE *stream)
  23.   {
  24.     /* Your implementation of ferror(). */
  25.   }
  26.   long int ftell(FILE *stream)
  27.   {
  28.     /* Your implementation of ftell(). */
  29.   }
  30.   int fclose(FILE *f)
  31.   {
  32.     /* Your implementation of fclose(). */
  33.     return 0;
  34.   }
  35.   int fseek(FILE *f, long nPos, int nMode)
  36.   {
  37.     /* Your implementation of fseek(). */
  38.     return 0;
  39.   }
  40.   int fflush(FILE *f)
  41.   {
  42.     /* Your implementation of fflush(). */   
  43.     return 0;
  44.   }
  45. }
这样之后, cout就随便用了:
  1. #include <stdio.h>
  2. #include <iostream>
  3. using namespace std;
  4. int main()
  5. {
  6.   cout << "Hello world\n";
  7.   return 0;
  8. }

zhuotuzi 发表于 2017-1-21 17:53 | 显示全部楼层
这个是C的吧,用的还是Printf
oayzw 发表于 2017-1-21 19:27 来自手机 | 显示全部楼层
考的编译器水平
 楼主| zhanzr21 发表于 2017-1-21 22:13 | 显示全部楼层
zhuotuzi 发表于 2017-1-21 17:53
这个是C的吧,用的还是Printf

iostream这块,我的确还没有搞通,所以调试打印用的是c lib的printf, iostream这部分正在研究中
不过容器,算法,numeric这些是C++的, C++和C共存是很常见的, 不能说用个printf就一定是C
事实上大多数C++项目都是混着来的
zhuotuzi 发表于 2017-1-23 20:47 | 显示全部楼层
仔细看了一下,真是C++,我只需过C不太了解面向对象。
 楼主| zhanzr21 发表于 2017-2-5 19:55 | 显示全部楼层
 楼主| zhanzr21 发表于 2017-2-5 20:12 | 显示全部楼层
重定向关键就是把语言自带的文件系统的调用给覆盖掉
至于还要使用文件系统, 那么文件操作不能再叫做fopen, fclose, fwrite, fread, fput这样的名字了,
比如FATFS的文件操作函数分别叫做f_open, f_close, 什么的, 都加了一个_
语言自带的file系列函数只是实现了文件系统的一部分, 如果在Windows, Linux这种环境就可以依赖系统的文件系统来操作文件, 而XMC1100这种环境, 语言所带的file系列函数是不能单独操作文件的
plsbackup 发表于 2017-2-5 22:53 | 显示全部楼层
为什么不用C语言开发呢。
 楼主| zhanzr21 发表于 2017-2-6 00:25 | 显示全部楼层
plsbackup 发表于 2017-2-5 22:53
为什么不用C语言开发呢。

这个问题不好回答, 谁爱用什么就用什么, 个人自由
发这个只是给C++的工程师参考一下
dengxindieying 发表于 2017-2-16 23:38 | 显示全部楼层
高级,面向对象
HMingS 发表于 2017-3-6 16:01 | 显示全部楼层
,我觉得C++会在以后的编程中渐渐被推广开来,本身我还是有倾向与使用C++编程的
yoyofair 发表于 2017-3-6 19:46 | 显示全部楼层
plsbackup 发表于 2017-2-5 22:53
为什么不用C语言开发呢。

当程序代码量超过10万行后,你会发现用C++真的超级爽。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:每天都進步

91

主题

1017

帖子

34

粉丝
快速回复 在线客服 返回列表 返回顶部