今天这篇文章有点复杂,大家要注意一点看啦!

我们知道KEIL是支持C 的,网上一搜索也能找到一些使用C 的方法,无非是在Keil里的options->C/C ->Misc Controls里添加—cpp,如果要支持c 11,还需要指定—cpp11。事实上这样的C 并不是完整意义的上的C ,阿圆测试过,有好多C 的新功能都是没有办法实现的。这里需要注明的是,在KEIL5.18a以前的版本(包括5.18a)所支持的Arm Compiler只有ARM Compiler 5以及更低的版本,C 11支持不完整,而对C 11有完整支持就必须要使用Arm Compiler 6 AC6

为了使用对C 11有完整支持的Arm Compiler 6(AC6),今天所使用的KEIL MDK版本至少应用为5.20版本以上(Arm Compiler 6.4)

本文中阿圆使用的AC6为6.7版本,为KEIL MDK 4.24a所自带的AC6编译器

这里需要注意的是AC6仅支持以下系统

所以大家在试验之前,一定要检查下自己所使用的环境,否则就会浪费时间啦。

关于MDK的下载以及和谐办法,大家自行百度解决啦~

它就是Code Generation里的Use MicroLIB,默默地被勾上。

那么他最主要的作用是什么呢?

如果是C/C standardlib 还支持

然而真正的C 开发是不能链接microlib的,因为他只是标准C library的一个精简集。网上能查到microlib的一些限制,这里阿圆列举一些出来

正常情况下,在STM32CubeMX通过成的.s文件里可以看到一个__main函数,这个就是microlib的入口地址,他会完成上述的初始化动作,最后跳转到我们熟悉的main

stm32f103c8t6怎么用电脑进行编程(话说嵌入式重磅)(1)

刚才也说过我们要实现真正的C 编程,就不能链接microlib,如果不链接microlib,就会默认链接到我们的C/C 标准库。

现在开始,首先依然是使用STM32CubeMX生成一个带串口的工程,阿圆有依旧是STM32F437ZGT6,工程名为ARMCCTest,要使用完整的C 11特性就必须使用AC6,这里把ARM Compiler设置为V6.7,并勾掉Use MicroLib

stm32f103c8t6怎么用电脑进行编程(话说嵌入式重磅)(2)

这里根据ARM官方的建议,检查下Short enums/wchar是否勾上

stm32f103c8t6怎么用电脑进行编程(话说嵌入式重磅)(3)

这样就设置好了。

但是呢,如果就这样去编译,会有一堆的编译错误

主要是__weak编译失败

stm32f103c8t6怎么用电脑进行编程(话说嵌入式重磅)(4)

AC6己经不支持直接声明 __weak了,需要使用 __attribute__((weak))替代。这里不建议使用全局替代的方法, 如下图所示

stm32f103c8t6怎么用电脑进行编程(话说嵌入式重磅)(5)

因为如果你的的工程里有包含了C 文件,这种方法可能把系统库里的__weak也给替换了,阿圆吃过大亏!结果都重装KEIL了

好的,为了测试C 11的功能,我们新建一个CppTest.cpp文件,为了保持和C的兼容性呢我们把main挪到了cpp文件里,将原来Keil生成的main改为cmain即可

stm32f103c8t6怎么用电脑进行编程(话说嵌入式重磅)(6)

stm32f103c8t6怎么用电脑进行编程(话说嵌入式重磅)(7)

这里看到有一个Test类,这就是我们需要对C 11特性进行测试的类

stm32f103c8t6怎么用电脑进行编程(话说嵌入式重磅)(8)

这里面还包含了一个Base和Derived类

stm32f103c8t6怎么用电脑进行编程(话说嵌入式重磅)(9)

这样一个简单的C 测试用例就写好了!

但是!这样是不能执行的!一旦执行系统在跳到__main时之后就跑飞了!

大家可以想一想这是怎么一回事?

留白

留白

留白

好啦,不卖关子啦,事实上阿圆也阿了近两天的时间才找到解决办法,一开始认为是heap和stack没有初始化好,尝试了好久均未成功,后来在网上得到启发,这个问题是出在STDIO初始化上

如果要使用C/C 标准库就要对其STDIO进行Retarget的,很简单,但却是非常关键的一步,就是这么一回事啦。

下载ARM官方的retarget文件,并加入到工程当中

下载链接

http://infocenter.arm.com/help/topic/com.arm.doc.faqs/attached/3844/retarget.c

稍微进行小修改,把它重定向到串口就可以啦!

stm32f103c8t6怎么用电脑进行编程(话说嵌入式重磅)(10)

现在就可以把代码编译运行一下,从SSCOM看到代码正常运行并输出了log

stm32f103c8t6怎么用电脑进行编程(话说嵌入式重磅)(11)

都运行成功了!

要问阿圆为什么没有使用std::cout,我也觉得很奇怪啦

../Src/CppTest.cpp(44): error: no member named 'cout' in namespace 'std'

std::cout<< "adsaf" ;

~~~~~^

上面只是简单测试了C vector容器,智能指针,auto变量和lambda表达式,当然C 11的内容比这要广泛得多,大家可自行测试!

不过要使用上完整的C 11代价也是非常大的(未开启优化 -O0编译)!上面的代码几乎不做什么有用的功能其大小竟然达到了可怕的231K!

stm32f103c8t6怎么用电脑进行编程(话说嵌入式重磅)(12)

大家还Hold住吗!哈哈!

,