传感器
M2M 云计算
智慧城市
电子标签
二维码
IPV6

未来
物联网
让一切想象变成现实!

未来物联网为您提供物联网资讯,物联网新闻,物联网技术,物联网会议,

物联网企业,物联网行业资讯网站,全球物联网技术及物联网应用最新动态。

一分钟物联网:香不香?面向对象的嵌入式代码,Mbed 初探

[复制链接]
润洲物联   发表于 2021-2-6 17:45:18   查看: 593 帖子

Mbed OS 是一个基于C++的面向对象的嵌入式实时操作系统,那么对于 “恐C++” 的老牌嵌入式工程师们,使用Mbed OS 是不是有比较大的门槛呢?本文带大家一起体验下。


  • 本文所有代码均基于官网实例改编,仅使用Mbed OS标准API接口,不含任何三方代码。
  • 代码中安杰尼尔尽量不加额外注释,让懂与不懂C++的码友们体验下是否能够读明白。
  • 如果想运行下的话,可以花5分钟温习下前文《一分钟物联网:简而不凡的无环境线上开发模式,Mbed 初探》

一分钟物联网:香不香?面向对象的嵌入式代码,Mbed 初探-1.jpg

一分钟物联网


嵌入式为什么需要面向对象?

此话题已经是老生常谈。大家可能已有体会,除了少数如工业流程控制的场景外,绝大部分消费类嵌入式应用逻辑,都是基于响应用户/硬件事件而触发运作的,所以嵌入式开发天然地适合使用面向对象的编程方式来实现

那么为什么之前很少用JAVA, C++做嵌入式开发而普遍是汇编和C呢?原因一个字,“穷”!安杰尼尔的老话,在 “一个字节分八瓣花” 的时代,咱们片上就那么点儿资源,还是用不起占用资源相对较多的面向对象语言(不绝对)。同时,刀耕火种年代,汇编和C更适合与寄存器和硬件打交道,而对我们 “大嵌入式工程师们” 来说,用面向过程的语言实现应用逻辑,简直小菜一碟!

那么,4位,8位单片机逐渐被淘汰,32位,甚至64位处理器大行其道的时候,我们还用自己拿着汇编和C造轮子么?我们还能在个人作坊里捋顺动则十万百万行的“小程序”线性逻辑么?

一分钟物联网:香不香?面向对象的嵌入式代码,Mbed 初探-2.jpg

程序复杂度爆炸式增长


停止废话,上代码:闪灯程序升级版!

/* mbed Microcontroller Library * Copyright (c) 2019 ARM Limited * SPDX-License-Identifier: Apache-2.0 */#include "mbed.h"#include "platform/mbed_thread.h"// Blinking rate in milliseconds#define BLINKING_RATE_MS    500int main(){    // Initialise the digital pin LED1 as an output    DigitalOut led1(LED1);    DigitalOut led2(LED2);    DigitalOut led3(LED_RED);     while (true) {        led1 = !led1;        led2 = !led1;                led3 = !led2;                thread_sleep_for(BLINKING_RATE_MS);    }}按键响应程序也是嵌入式惯例?

/* * Copyright (c) 2017-2020 Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 */#include "mbed.h"InterruptIn button(USER_BUTTON);DigitalOut led_button(LED1);DigitalOut led_flash(LED2);void flip(){    led_button = !led_button;}int main(){    button.rise(&flip);  // attach the address of the flip function to the rising edge    while (1) {          // wait around, interrupts will interrupt this!        led_flash = !led_flash;        ThisThread::sleep_for(250);    }}没有timer不算嵌入式!

/* * Copyright (c) 2006-2020 Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 */#include "mbed.h"Ticker flipper;DigitalOut led1(LED1);DigitalOut led2(LED2);void flip(){    led2 = !led2;}int main(){    led2 = 1;    // the address of the function to be attached (flip) and the interval (2 seconds)    flipper.attach(&flip, 2.0);     // spin in a main loop. flipper will interrupt it to call flip    while (1) {        led1 = !led1;        ThisThread::sleep_for(200);    }}内置的 printf 有没有在用 Rich OS的感觉?

/* * Copyright (c) 2017 - 2020 Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 */#include "mbed.h"#define MAX_THREAD_INFO 10mbed_stats_heap_t heap_info;mbed_stats_stack_t stack_info[ MAX_THREAD_INFO ];int main(){    debug("\nThis message is from debug function");    debug_if(1, "\nThis message is from debug_if function");    debug_if(0, "\nSOMETHING WRONG!!! This message from debug_if function shouldn't show on bash");    printf("\nMemoryStats:");    mbed_stats_heap_get(&heap_info);    printf("\n\tBytes allocated currently: %ld", heap_info.current_size);    printf("\n\tMax bytes allocated at a given time: %ld", heap_info.max_size);    printf("\n\tCumulative sum of bytes ever allocated: %ld", heap_info.total_size);    printf("\n\tCurrent number of bytes allocated for the heap: %ld", heap_info.reserved_size);    printf("\n\tCurrent number of allocations: %ld", heap_info.alloc_cnt);    printf("\n\tNumber of failed allocations: %ld", heap_info.alloc_fail_cnt);    mbed_stats_stack_get(&stack_info[0]);    printf("\nCumulative Stack Info:");    printf("\n\tMaximum number of bytes used on the stack: %ld", stack_info[0].max_size);    printf("\n\tCurrent number of bytes allocated for the stack: %ld", stack_info[0].reserved_size);    printf("\n\tNumber of stacks stats accumulated in the structure: %ld", stack_info[0].stack_cnt);    mbed_stats_stack_get_each(stack_info, MAX_THREAD_INFO);    printf("\nThread Stack Info:");    for (int i = 0; i < MAX_THREAD_INFO; i++) {        if (stack_info.thread_id != 0) {            printf("\n\tThread: %d", i);            printf("\n\t\tThread Id: 0x%08lX", stack_info.thread_id);            printf("\n\t\tMaximum number of bytes used on the stack: %ld", stack_info.max_size);            printf("\n\t\tCurrent number of bytes allocated for the stack: %ld", stack_info.reserved_size);            printf("\n\t\tNumber of stacks stats accumulated in the structure: %ld", stack_info.stack_cnt);        }    }    printf("\nDone...\n\n");}两种串口对象够不够大家用?

BufferedSerial 对象,用于串口发送接收,所有Mbed Enable平台均默认支持

一分钟物联网:香不香?面向对象的嵌入式代码,Mbed 初探-3.jpg

对象集成关系


/* * Copyright (c) 2020 Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 */#include "mbed.h"// Maximum number of element the application buffer can contain#define MAXIMUM_BUFFER_SIZE                                                  32// Create a DigitalOutput object to toggle an LED whenever data is received.static DigitalOut led(LED1);// Create a BufferedSerial object with a default baud rate.static BufferedSerial serial_port(USBTX, USBRX);int main(void){    // Set desired properties (9600-8-N-1).    serial_port.set_baud(9600);    serial_port.set_format(        /* bits */ 8,        /* parity */ BufferedSerial::None,        /* stop bit */ 1    );    // Application buffer to receive the data    char buf[MAXIMUM_BUFFER_SIZE] = {0};    while (1) {        if (uint32_t num = serial_port.read(buf, sizeof(buf))) {            // Toggle the LED.            led = !led;            // Echo the input back to the terminal.            serial_port.write(buf, num);        }    }}
UnbufferedSerial 对象,用于不需要缓存的告诉/自处理串口应用场景

一分钟物联网:香不香?面向对象的嵌入式代码,Mbed 初探-4.jpg

对象集成关系


/* * Copyright (c) 2020 Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 */#include "mbed.h"// Create a DigitalOutput object to toggle an LED whenever data is received.static DigitalOut led(LED1);// Create a UnbufferedSerial object with a default baud rate.static UnbufferedSerial serial_port(USBTX, USBRX);void on_rx_interrupt(){    char c;    // Toggle the LED.    led = !led;    // Read the data to clear the receive interrupt.    if (serial_port.read(&c, 1)) {        // Echo the input back to the terminal.        serial_port.write(&c, 1);    }}int main(void){    // Set desired properties (9600-8-N-1).    serial_port.baud(9600);    serial_port.format(        /* bits */ 8,        /* parity */ SerialBase::None,        /* stop bit */ 1    );    // Register a callback to process a Rx (receive) interrupt.    serial_port.attach(&on_rx_interrupt, SerialBase::RxIrq);}
时间有限,今天就不继续拷贝粘贴了,下面是 Mbed OS 默认支持的 跨平台标准API接口 列表,大家可自行体验 “配套的标准化齿轮”是否好用,详细可搜索Mbed到官网了解更多。

一分钟物联网:香不香?面向对象的嵌入式代码,Mbed 初探-5.jpg



一分钟物联网:香不香?面向对象的嵌入式代码,Mbed 初探-6.jpg



一分钟物联网:香不香?面向对象的嵌入式代码,Mbed 初探-7.jpg



一分钟物联网:香不香?面向对象的嵌入式代码,Mbed 初探-8.jpg



一分钟物联网:香不香?面向对象的嵌入式代码,Mbed 初探-9.jpg



一分钟物联网:香不香?面向对象的嵌入式代码,Mbed 初探-10.jpg



一分钟物联网:香不香?面向对象的嵌入式代码,Mbed 初探-11.jpg



一分钟物联网:香不香?面向对象的嵌入式代码,Mbed 初探-12.jpg
 郑重声明:本文仅代表作者个人观点,与未来物联网(wlit.cn)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
回复

使用道具 举报

QQ|Archiver|手机版|未来物联网 ( 鲁ICP备17019744号-2 ) 百度统计

GMT+8, 2021-6-13 10:05 , Processed in 0.190456 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表