参考手册从总体上、运行时、配置、模块技术和API方面对MBED OS进行了全面的介绍。
在阅读参考手册的同时,翻译了部分资料。
1 概述
1.1 Mbed OS 参考手册
应用代码采用C++编写,使用Mbed OS提供的API,在不同的微处理器上按照统一的编程实现。便于应用的开发。
基本架构图
2 运行时
2.1 引导
2.1.1入口点
Mbed OS提供了两个入口点
· main(void)
-所有的标准应用都使用该代码入口点
· mbed_main(void)
- main前的入口点,也可以使用这个编写应用入口点
当执行到入口点,用户期望在执行应用代码前完成全部的系统初始化。以下功能必须在执行到入口点前完成。
· 平台底层初始化
· 堆、栈初始化
· 中断向量拷贝到RAM(批注:为什么呢?)
· 标准库初始化
· RTOS初始化,并启动任务调度
2.1.2重定向
Mbed OS重定向了多个标准C库函数,用户可以在远程嵌入式目标设备上按照预计熟悉的方式使用它们
· stdin
, stdout
, stderr
- 标准输入、输出、错误。这些文件并重定向到串口,就像printf \ getc一样使用标准输入、输出功能
· fopen
, fclose
, fwrite
, fread
, fseek
-文件操作函数。用户通过串口使用,就像内建的文件系统一样
· opendir
, readdir
, closedir
-目录操作函数。用户可以操作内建的文件系统
· exit
-让开发板停止执行,标准文件句柄从缓存提交,关闭ARM支持的半主机连接并进入无限循环。若返回指定的错误代码,开发板通过LED等进行闪烁提示。
· clock
- 时钟有平台的微秒计算器重载。
2.2 内存
内存分布详见原始资料
2.2.1可读写内存
分两种内存,静态内存和动态内存(通过函数分配和释放)。静态内存在编译时连续分配并不会改变空间大小。动态内存在运行时分配。例如确定,FORK和加入一个线程、或构建或析构一个对象时,使用的内存增加或减少。系统按照不同的方式使用
· Static:
· Vector table (read and write).
· Global data.
· Static data.
· Stacks for default threads (main, timer, idle andscheduler/ISR).
· Dynamic:
· Heap (dynamic data).
· Stacks for user threads. Mbed OS dynamically allocates memory onheap for user thread's stacks.
栈检查在所有的线程都是打开的,若检测到栈溢出,报内核错误
2.2.2Flash
Flash is a read onlymemory (ROM) that contains:
· Vector table (read only).
· Application code.
· Application data.
· Optional bootloader.
2.2.3静态内存优化
2.2.3.1 移除不使用的模块
以一个简单的闪灯示例程序为例,主要的内存如下。(批注:在没有考虑应用使用的内存情况下,需要约12K的内存,要求的内存空间还是比较大的。)
features/frameworks
模块包含了
Mbed OS
测试工具。即使不再需要测试程序。因此,每个
BIN
文件包含了测试入口。移除这些模块可减少
RAM
和内存
printf和UART
链接器可以移除程序不使用的模块,还是以闪灯示例为例。主模块没有使用printf或UART。但是,每个模块处理TRACE和ASSET时,通过重定,将他们的错误消息通过printf到串口输出。因此强制将printf 和UART编译到项目中,并占
可通过修改mbed_app.json
配置文件中的配置参数,设置NDEBUG可以禁止错误日志从串口输出。
注意,不同的编译环境,结果可能不一样。
2.2.3.1.2 嵌入式目标板
还可利用只运行在嵌入式系统的特性进行优化。若若C++应用运行在PC机上,在进入main前,操作系统会完成全局C++对象的构建。还会在程序结束时析构这些对象。编译器注入的代码对应用也有一定的影响。
· 编译器注入的代码要占用内存
· 即使应用不需要使用动态内存方式,也需要在BIN文件中包含malloc以便实现动态分配。
若运行在嵌入式系统中,不需要在应用程序退出时销毁全局对象,应为应用永远不会终止。可以通过在应用的启动阶段使用编译器选项进行屏蔽
- ARMCC: override
__aeabi_atexit
,__cxa_atexit
and__cxa_finalize
. The methodology is explained here.
2.3 执行
2.3.1线程
应用程序执行在主线程,但不是只有该线程在执行,还有几个系统服务线程在运行。
· 应用主线程,缺省有4KB的栈空间,可通过mbed_app.json
来配置
main
栈空间。若使用
KEIL
等开发环境,应直接修改
MBED_CONF_APP_MAIN_STACK_SIZE
· 空线程,在没有其他激活前程的情况,运行该线程。主要是为了保证在没有其他线程的情况,不要让处理器进行循环,占用功耗,而是只要一有可能就进入SLEEP。
· 定义器线程。这个线程主要处理用户时间对象。
注意,不要再使用RtosTimer,而是只用EventQueue
2.3.2执行模式
两种模式执行
· 线程模式:缺省的应用模式,所有用户线程按照这个模式执行,线程有明确的线程栈内存空间。
· 中断模式,系统代码和中断函数在这种模式先执行,使用系统ISR占的静态内存空间
2.3.2.1 中断模式
所有的中断服务器按照这种模式执行,在中断服务函数里同样可以使用RTOS的API。两种模式的主要差别就是句柄模式中的代码不能使用等待,要尽可能执行完成后马上返回线程模式。
· 不能使用MUTEXT
· 不能使用等待,所有时间相关的参数要配置成0
中断服务程序举例:
3 配置
3.1 配置系统
Mbed OS配置系统,是其构建中的一部分工具,用于定义编译时的配置采纳数。每个库对应mbed_lib.json
定义一些配置参数,mbed_app.json
可以覆盖库里定义的采纳数。配置定义使用
JSON
。一些示例如下。
(批注:在使用第
3
方开发工具时,要通过其他的方式来配置。)
· 应用获取数据的采样时间
· 新创建线程的缺省栈空间
· 串口通讯库的接收BUFFER
MBED OS配置系统手机各个库和应用的配置信息,生成一个配置头文件mbed_config.h
,将所有的配置转换成
C
预定宏。该头文件放在编译目录下,
每个库是指可以进行代码复用的代码模块。
现有版本的所有配置文件:
drivers\mbed_lib.json
events\mbed_lib.json
cellular\mbed_lib.json
FEATURE_COMMON_PAL\mbed-trace\mbed_lib.json
FEATURE_COMMON_PAL\nanostack-hal-mbed-cmsis-rtos\mbed_lib.json
FEATURE_COMMON_PAL\sal-stack-nanostack-eventloop\mbed_lib.json
FEATURE_LWIP\lwip-interface\mbed_lib.json
FEATURE_UVISOR\mbed_lib.json
filesystem\mbed_lib.json
filesystem\littlefs\mbed_lib.json
frameworks\utest\mbed_lib.json
lorawan\mbed_lib.json
nanostack\FEATURE_NANOSTACK\mbed-mesh-api\mbed_lib.json
nanostack\FEATURE_NANOSTACK\sal-stack-nanostack\mbed_lib.json
netsocket\mbed_lib.json
netsocket\cellular\generic_modem_driver\mbed_lib.json
nvstore\mbed_lib.json
storage\FEATURE_STORAGE\cfstore\mbed_lib.json
platform\mbed_lib.json
rtos\mbed_lib.json
FEATURE_COMMON_PAL\mbed-trace\module.json
FEATURE_BLE\module.json
FEATURE_COMMON_PAL\mbed-client-randlib\module.json
FEATURE_COMMON_PAL\mbed-coap\module.json
FEATURE_COMMON_PAL\nanostack-libservice\module.json
FEATURE_COMMON_PAL\sal-stack-nanostack-eventloop\module.json
nanostack\FEATURE_NANOSTACK\mbed-mesh-api\module.json
用custom_targets.json
来配置目标板
在参考文档里,介绍了如何配置参数:
a) MBED CLI环境下如何查看配置
b) 代码中如何使用配置数据:
MBED配置系统将各个配置汇总、转换并保存到 mbed_config.h
文件中,
宏定义按如下规则MBED_CONF_+
库
/
应用名
+
配置参数
编译工具指定
mbed_config.h
是每个代码的第
1
个包含头文件,不用再代码中包含
c) mbed_app.json
, mbed_
lib.json
中的配置参数
d)
mbed_app.json
会覆盖
mbed_lib.json
中定义的参数
e) mbed_
lib.json
格式说明
f) mbed_app.
json 格式说明
之后主要介绍了主要模块:平台、驱动、RTOS、连接模块的配置参数。但没有源代码其他模块的配置参数
3.2 6LoWPAN and Thread Mesh
Thread,由三星、Nest、ARM、Big Ass Fans、飞思卡尔和Silicon Labs公司联合推出, 是一种基于IP的无线网络协议,用来连接家里的智能产品。
4 技术
技术主要介绍通讯相关的3个部分:
1、以太网,MBED OS采用lwip库支持以太网,支持IPV4和IPV6,只支持IP包的处理
2、无线局域网:支持WIFI,支持802.11.A/B/G/N. WIFI协议主要硬件模块和驱动实现, mbed os在此基础上实现一个仿真以太网接口或网络栈API
3、Thread + 6LoWPAN中的主要技术月以及如何组网:大致浏览了一下,主要技术可通过其他途径理解。
通过 6LoWPAN 技术支持 IPv6 。Thread可支持 250 个以上设备同时联网,能够覆盖到家中所有的灯泡、开关、传感器和智能设备。优化了功耗,超低能耗,设备可以运行数年。此外,Thread 是基于 ZigBee 的,也就是说原有的 ZigBee 设备只需更新软件即可兼容 Thread。综合来看,Thread 很可能像 Homekit、高通的 开源框架 AllJoyn 一样,是一种在顶层工作的顶层架构(百度百科)
网络主要包含以下元素:
BR:Border router 边界路由器,在6LoWPAN与IPV6网络之间作转换。MBED OS不支持IPV4,建议通过IPV6的隧道技术支持IPV4.BR对接入节点进行认证,并跟踪网络路由
router : 路由节点,进行包的路由功能,这种节点不允许睡眠。需要这种节点实现拓扑或MESH网。
HOST:主机,主机类节点不路由包,只有一个父节点路由包
Sleepy Host:这种主机节点周期性的睡眠和唤醒其无线功能
主要的网络结构
星状网:
除了BR外,都是主机节点。主机节点可以低功耗的主机节点
MESH、TREE网络
每个节点都是路由节点。使用RPL协议建立路由。每个节点选择一个基本父节点。因此网络看起来像一个树。因为每个包在路由节点都要重新传送,称为一跳HOP。因此随着网络的增加,
·