本帖最后由 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)
补充: 研究了一下, 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;
}
|
|