本帖最后由 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程序员感到麻烦, 其实是为了让程序更严谨,降低后面出问题的概率
- #include <cstdint>
- #include <cstring>
- #include <cstdio>
- #include <algorithm>
- #include <vector>
- #include <numeric>
- #include <stdlib.h>
2.声明一个vector, 理论上这个vector刚开始没有内容,但是还是要占一点空间, 至于占多少,跟编译器的实现有关
- std::vector<uint32_t> vD;
3.生成10个随机数,push_back进到刚刚那个vector中去, 第一个元素加进去的时,这个vector的capacity就增加到32, 这个32也是由编译器的实现决定的,如果是电脑上的编译器,一般是500, 1000这样.
- vD.clear();
- printf("generate 10 rand number and push to the vector:\n");
- for(i=0; i<10; ++i)
- {
- vD.push_back((uint16_t)rand());
- printf("%u ", vD.at(i));
- }
这里没有用iostream中的输出std::cout,是因为我这个重定向用了ITM, 跟Keil Runtime 有点冲突, 暂时没有找到解决办法, 后面找到了再来更新, 暂时先用printf顶住.
4.使用algorithm与numeric中的库调用:sort与accumulate, 排序, 累加 ,这里看出C++的好处,写复杂程序的时候, 这一点尤其突出
- printf("\nNow sort them and the result:\n");
-
- std::sort(vD.begin(), vD.end());
-
- for(i=0; i<10; ++i)
- {
- printf("%u ", vD.at(i));
- }
-
- 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关键代码:
- #include <stdio.h>
- namespace std {
- struct __FILE
- {
- int handle;
- /* Whatever you require here. If the only file you are using is */
- /* standard output using printf() for debugging, no file handling */
- /* is required. */
- };
- FILE __stdout;
- FILE __stdin;
- FILE __stderr;
- int fgetc(FILE *f)
- {
- /* Your implementation of fgetc(). */
- return 0;
- }
- int fputc(int c, FILE *stream)
- {
- /* Your implementation of fputc(). */
- }
- int ferror(FILE *stream)
- {
- /* Your implementation of ferror(). */
- }
- long int ftell(FILE *stream)
- {
- /* Your implementation of ftell(). */
- }
- int fclose(FILE *f)
- {
- /* Your implementation of fclose(). */
- return 0;
- }
- int fseek(FILE *f, long nPos, int nMode)
- {
- /* Your implementation of fseek(). */
- return 0;
- }
- int fflush(FILE *f)
- {
- /* Your implementation of fflush(). */
- return 0;
- }
- }
这样之后, cout就随便用了:
- #include <stdio.h>
- #include <iostream>
- using namespace std;
- int main()
- {
- cout << "Hello world\n";
- return 0;
- }
|