完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
大多数嵌入式工程师使用C语言来编写Cortex-M系列MCU 的程序,大家总觉得C++是用来编写Windows 或者Linux 应用程序的。特别是硬件工程师,也许压根就没有使用C++来编写程序。
当我们阅读Mbed OS 的代码时却发现,许多是使用C++来编写的。C++是一种功能强大的面向对象的程序设计语言,在嵌入式系统软件开发中使用C++,会获得意想不到的简洁和喜悦。 事实上,arduino 的程序设计语言也是C/C++。在arduino中也可以设计C++的类。许多arduino的库都是C++的类。Arm keil 中的MDK-ARM V5.14 也支持C++程序设计语言。 但是身边的嵌入式工程师使用C++语言特性的并不多见。 下面我们就从嵌入式程序员的角度来谈谈C++。 对C++语言的误解 对于嵌入式程序员来讲,对C++语言有一些误解: C++太慢 C++ 生成的目标代码过于庞大 C++ 不是ROMable的 C++ 库过于庞大 抽象造成了低效率 虚拟函数太慢 所以这些观点都是错误的。据有关文献表明,C++的源代码可能比C++程序多一些,但是目标代码并不比C语言产生的代码大和慢。最多只有10%的差异。 C++的版本 C++ 是一种面向对象的程序设计语言,它是1979年美国贝尔实验室在C语言的基础上发展起来的。国家标准化组织对C++建立了标准化,之前稳定的版本是C++98版本。 C++的版本为C++11 是ISO 2011年的标准版本,C++14 是2014年的标准版本,C++17 是2017年的标准版本。 C++是C语言的一个超集,所以在C++编译环境下,我们依然可以使用C编写程序。 C++ 的特点 C++和C最大的区别就是C++是面向对象的程序设计语言。而C是面向过程的程序设计语言。通俗地讲,C++是以数据为中心的,而C是以流程为中心的。学习C++ 程序设计的关键不是去熟悉C++的语法,而是要从以流程为中心转向对象为中心的思维模式。 C++最重要的概念就是类和对象。 对象(Objects)是要程序处理的任何一个物体,我觉得可以翻译成物体,事物等等。面向对象,***翻译成 物件导向,我觉得更为贴切一点。对于嵌入式程序而言,软件更加接近物理物体。比如一个引脚,一个马达,一个SPI端口,甚至于一台CNC机床,一台注塑机。在C++ 程序中都被看做一个和多个对象。 它是如何做到的呢?使用的最基本的方法就是简化和抽象。在面向对象的程序设计语言中,将对象抽象成了一组数据,以及对这些数据操作的函数,并称之为类(class)。 形式上,就好比将几个函数加入到了结构类型(struct)中。在 C 中,结构是数据的凝聚,它将 数据捆绑在一起,使得我们可以将它们看作一个包。它们的处理可能在其它的地方。然而将函数也放在这个包内,结构就变成了新的创造物,它既能描述属性(就像 C中的 struct 能做的一样),又能描述行为,这就形成了对象的 概念。对象是一个独立的有约束的实体,有自己的记忆和活动。 为了加深印象,我们来举一些例子: 例如:我们来定义一个循环缓冲区类: 循环队列是嵌入式程序设计中常用的数据结构,例如在 串口UART通信中,如果使用终端方式就需要使用循环队列。它大概需要下面几个数据结构和操作: 缓冲区buffer 输入指针 input_index; 输出指针 output_index; 计数器 counter 操作程序包括 init() put(char v) char get() C语言的代码为: uint8_t buffer[SIZE]; int input_index; int output_index; int counter void init() { input_index=0; output_index=0; counter=0; } void put(uint8_t value) { buffer[input_index++]=value; if (input_index==SIZE-1) input_inedx=0; counter++; } uint8_t get(){ int temp; temp=buffer[output_index++]; if (output_index==(SIZE-1)) output_index=0; counter--; } 如果使用C++来编写一个循环队列的类: class circular_buffer { public: circular_buffer(); put(uint8_t val); uint8_t get(); private: int input_index; int output_index; int buffer[SIZE]; } circular_buffer:: circular_buffer() { input_index=0; output_index=0; counter=0; } void circular_buffer:: put(uint8_t value) { buffer[input_index++]=value; if (input_index==SIZE-1) input_inedx=0; counter++; } uint8_t circular_buffer:: get(){ int temp; temp=buffer[output_index++]; if (output_index==(SIZE-1)) output_index=0; counter--; } 对象是类的实例,就好比变量是类型的实例。上面的类实例化 circular_buffer mybuffer; 从形式上看,没有太多的变化,实际上,我们使用Class 描述的循环队列,不那么凌乱。更像是一个硬件的元器件。面向对象程序设计是我们用更接近物理特性的方式来描述物件。用类描述的循环缓冲区更像一个硬件器件。这才是OOP 的独特魅力。 如果我们在程序中使用多个循环缓冲区的话,使用类(CLASS) 就显得简洁了,只要写成: circular_buffer inputBuffer; circular_buffer outputBuffer; 通过C++ 的类,我们将循环缓冲区变成了像一个元器件,我们不在需要关心内部的实现细节,而只需要关心它给使用者呈现出来的性能就可以了。我们也可以使用一个符号来表示。 我们有必要再去学习C++呢?我也疑惑过,以至于很长时间没有去关心Arm公司C++编译器。直到Mbed OS 中大量地使用C++来编写程序,才开始认真地开始研究C++在嵌入式程序设计中的应用。 从C语言转向C++,不仅仅是你要学习新的语言规则,而是要改变编程的思维方式。最有价值的可能不是那些已存在的代码库(给出合适的工具,可以转变它),而是已存在的头脑库。一旦从C语言面向过程的方式转变为面向对象程序设计方式。你的效率会大大提高。所以C程序员学习C++的一项值得的投资。程序员是在用问题空间的术语描述问题的解(例如“把锁链放在箱子里”),而不是用计算机的术语,也就 是解空间的术语,描述问题的解(例如“设置芯片的一位即合上继电器”)。程序员所涉及的是 较高层的概念,一行代码能做更多的事情。 在MBed OS 中,硬件接口都是使用类来定义。使程序员不需要关注细节,就可以直接访问和控制硬件电路。例如下面这些都是接口类。 DigitalOut 数字输出类 构造函数 DigitalOut myled(PF_14); 它真正指定了STM32F429 的一个GPIO 脚 成员函数 write (int value); read ();; 使用方式: myled.write(1); myled=1; myled=!myled; 看到了吧?使用C++定义的硬件类,使我们控制GPIO 变得非常的方便。 使用C++ 的类,和类似硬件设计那样,利用简单的功能电路构造构建了一个功能更强大,更智能的硬件零部件。在modular-2 电脑中,所有的I/O 接口板都对应封装了一个接口类(interface Class)。将硬件抽象成了软件的类。 应用程序不再需要了解IO 模块的硬件细节,只要了解接口类就好了。正是由于Mbed OS 使用了C++类来设计API。才成就了Mbed OS 简单易学的特色。 C++ 的类是软件模块化设计的基石。使用类,可以几乎描述所以的物理部件的特性,比如步进电机,ADC 等等。 现在,我爱使用C++ 编写嵌入式程序,这个过程和使用各种元器件搭建PCB板,然后构成一个设备非常相似。编写一个好的类,就好像设计了一个芯片。既可以自己使用,也可以给朋友分享。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1934 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1710 浏览 1 评论
1187 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
785 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1752 浏览 2 评论
1992浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
827浏览 4评论
stm32f4下spi+dma读取数据不对是什么原因导致的?
281浏览 3评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
638浏览 3评论
645浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-2-3 11:43 , Processed in 0.819895 second(s), Total 74, Slave 58 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号