全面解析腾讯最新开源 loT 操作系统 TencentOS tiny!

百家 作者:CSDN 2019-09-24 11:39:38

作者?| 马超

责编 | 胡巍巍

出品 | CSDN(ID:CSDNnews)

近期腾讯低调地在GitHub上开源了自己的loT操作TencentOS tiny,截至发稿,已经累积了2000多个Star,引发了不小的关注。
由于笔者曾经做过CSDN的嵌入式大版当过很长时间的版主,所以第一时间到https://github.com/Tencent/TencentOS-tiny下载了全部的代码,第一时间为大家带来解读。


TencentOS tiny整体架构


TencentOS tiny 提供精简的 RTOS内核,其架构图如下:
? ? ? ?? ? ? ?
目前看其内核部分已经开发完成,并已经完全开源。
从目前TencentOS tiny?的情况看,腾讯入局物联网的相关链条已经规划完整:
? ? ? ??? ? ?
布署了TencentOS tiny?的的嵌入式开发板也已经制造出来,所以看来鹅厂在物联网时代对于入口的争夺也不会有丝毫的放松。
? ? ? ??? ? ?
下面我将对于TencentOS tiny?代码中内核及loT协议部分进行相关解读。


TencentOS tiny?内核信号量与互斥锁解读


TencentOS tiny?的官宣文档中对于其内核的描述如下:TencentOS tiny 实时内核包括任务管理、实时调度、时间管理、中断管理、内存管理、异常处理、软件定时器、链表、消息队列、信号量、互斥锁、事件标志等模块。
其中定时器、消息队列等在之前都有过相应介绍,这里就为大家来解读一下信号量与互斥锁的相关代码。
信号量与互斥锁的异同:
1.信号量与互斥锁最根本的不同点在于:互斥锁的取值只能是0或者1,而信号量的取值范围则可以定义。
2.信号量的作用域可以进程也可以是线程,而互斥锁只能是线程。简单来说互斥锁可以实现线程对于唯一资源的使用保护,而信号量则可以实现多线程或者进程间数量有限资源的使用保护。
从某种意义上讲互斥锁是只能一个资源可用的信号量。
关于TencentOS tiny?互斥体的实现,首先来看其数据结构具体解读如下:
typedef?struct?k_mutex_st?{

???pend_obj_t??????pend_obj;//pendding?obj的列表

???k_nesting_t?????pend_nesting;//个数

???k_task_t???????*owner;//现在所的拥有者

???k_prio_t????????owner_orig_prio;?//现在所的拥有者

???k_list_t????????owner_list;

}?k_mutex_t;
如果大家对于LINUX的内核也有足够了解,那么通过以上数据结构也能看到,TencentOS tiny?没有考虑自旋锁,其实也就是针对loT的场景进行了优化,裁减了多CPU的场景支持。
内核主要代码在此位置:https://github.com/Tencent/TencentOS-tiny/tree/master/kernel/core/tos_mutex.c

下面我们主要对于其pend操作函数进行解读如下:

__API__?k_err_t?tos_mutex_pend_timed(k_mutex_t?*mutex,?k_tick_t?timeout)

{

???TOS_CPU_CPSR_ALLOC();

???k_err_t?err;



???TOS_PTR_SANITY_CHECK(mutex);

???TOS_IN_IRQ_CHECK();



#if?TOS_CFG_OBJECT_VERIFY_EN?>?0u

???if?(!pend_object_verify(&mutex->pend_obj,?PEND_TYPE_MUTEX))?{

???????return?K_ERR_OBJ_INVALID;

???}

#endif

???TOS_CPU_INT_DISABLE();//将CPU锁住,防止其它进程进入

???if?(mutex->pend_nesting?==?(k_nesting_t)0u)?{?//没有等待

???????mutex_fresh_owner_mark(mutex,?k_curr_task);//将此mutex的owner置?为当前task

???????TOS_CPU_INT_ENABLE();//将CPU解锁

???????return?K_ERR_NONE;//返回成功

???}

???if?(knl_is_self(mutex->owner))?{

???????if?(mutex->pend_nesting?==?(k_nesting_t)-1)?{//等待数量如果超限则返回overflow

???????????TOS_CPU_INT_ENABLE();

???????????return?K_ERR_MUTEX_NESTING_OVERFLOW;

???????}

???????++mutex->pend_nesting;

???????TOS_CPU_INT_ENABLE();

???????return?K_ERR_MUTEX_NESTING;

???}

???if?(timeout?==?TOS_TIME_NOWAIT)?{?//如果锁已经被占用超时时间为不等待,则直接返回

???????TOS_CPU_INT_ENABLE();

???????return?K_ERR_PEND_NOWAIT;

???}

???if?(knl_is_sched_locked())?{//如果任务被锁定,则直接返回

???????TOS_CPU_INT_ENABLE();

???????return?K_ERR_PEND_SCHED_LOCKED;

???}



???if?(mutex->owner->prio?>?k_curr_task->prio)?{



???????tos_task_prio_change(mutex->owner,?k_curr_task->prio);//如果owner的优先级更低,也就是其数值更大,则调整优先级

???}



???pend_task_block(k_curr_task,?&mutex->pend_obj,?timeout);//阻塞pending的任务



???TOS_CPU_INT_ENABLE();//解锁CPU总线

???knl_sched();//解锁任务高度



???err?=?pend_state2errno(k_curr_task->pend_state);



???if?(err?==?K_ERR_NONE)?{//如果没有错误

???????TOS_CPU_INT_DISABLE();

???????mutex_new_owner_mark(mutex,?k_curr_task);//刷新mutex当前的owner

???????TOS_CPU_INT_ENABLE();

???}



???return?err;

}


TencentOS tiny?信号量的实现


首先来看k_sem_st的结构体:
typedef?struct?k_sem_st?{

???pend_obj_t??????pend_obj;//pending的列表

???k_sem_cnt_t?????count;//关键资源的数量

}?k_sem_t;
其信号量实现的相关代码,在以下位置:
https://github.com/Tencent/TencentOS-tiny/tree/master/kernel/core/tos_sem.c
下面我们对于post函数进行解读:
__STATIC__?k_err_t?sem_do_post(k_sem_t?*sem,?opt_post_t?opt)

{


???TOS_CPU_CPSR_ALLOC();//为CPU的CPSR进行预分配为后面恢复做准备



???TOS_PTR_SANITY_CHECK(sem);



#if?TOS_CFG_OBJECT_VERIFY_EN?>?0u

???if?(!pend_object_verify(&sem->pend_obj,?PEND_TYPE_SEM))?{

???????return?K_ERR_OBJ_INVALID;

???}

#endif



???TOS_CPU_INT_DISABLE();//CPU锁定防止其它进程入

???if?(sem->count?==?(k_sem_cnt_t)-1)?{//若资源数量为-1则返回超限

???????TOS_CPU_INT_ENABLE();

???????return?K_ERR_SEM_OVERFLOW;

???}



???if?(pend_is_nopending(&sem->pend_obj))?{//如果无pending的情况则直接返回

???????++sem->count;

???????TOS_CPU_INT_ENABLE();

???????return?K_ERR_NONE;

???}



???pend_wakeup(&sem->pend_obj,?PEND_STATE_POST,?opt);//唤醒pending的进程



???TOS_CPU_INT_ENABLE();//恢复CPU

???knl_sched();//恢复任务调度



???return?K_ERR_NONE;

}
所以从上述解读相信各位读者也能看到,TencentOS tiny的内核的确是被精心修减过,针对物联网场景做了相应的优化,去掉了一些没有必要的功能代码。

TencentOS tiny对于MQTT的实现


TencentOS tiny的官宣中对于IoT 协议栈介绍如下:TencentOS tiny 提供 lwip、AT Adapter、SAL 层,支持不同的网络硬件,例如以太网、串口 Wi-Fi、GPRS、NB-IoT、4G等通信模块。
TCP/IP 网络协议栈上提供常用的物联网协议栈,例如 CoAP、MQTT,支撑终端业务快速接入腾讯云。
其中MQTT可以算是物联网时代比较通用的基于IP网络的协议了,它基于发布/订阅消息模式,提供一对多的消息分发有三种消息传递服务质量。
1.最多一次,也就是消息发布者只会发布一次消息,不管对端是否收到也不会发布第二次。一般用于环境传感器的数据读取,因为一般环境传感器读取的密度很高,丢失几个数据并没有什么大问题。·
2.确保到达,这个一般用在数据非常重要的情况,发送端将不断重复发送直到对端响应收到。但这样可能出现数据重复。
3.确保恰好一次送达,确保消息正好到达一次。这个级别用于计费系统,重复或丢失的数据可能导致一定的损失。
由于MQTT适合在低带宽、高延时网络运行的特性所以在特联网中的应用很多。不过呢腾讯针对此部分的实现则是完全拷贝于Eclipse Paho项目(网址:http://www.eclipse.org/paho/) 个人制作的原理动画如下图:
? ? ? ??? ? ?
但是考虑到物联网终端其实仅需要MQTT的发布方即可,订阅方的代码其实没有太大必要保留,而且从目前发布支持的场景来看,MQTT一些通讯质量模式其实用处也不多,不过在这方面TencentOS tiny是没有做任何优化与裁减的。所以这应该也可以看做是TencentOS tiny的一个不足吧。


后记


随着移动互联网+智能硬件的不断发展,IoT的新业态大门徐徐开启,这里不但有众多互联网企业,也有传统家电甚至金融企业不断入局。但是与传统互联网软件+硬件的模式不同,物联网除了软、硬件外还多了一个侧面-场景,能将软、硬件及场景整合化一的公司才能笑到最后。
就像HTML整合了互联网一样,MQTT等loT协议会是整合全链条的利器,所以最后笔者也呼吁各方除了重视操作系统内核外也需要大力参与loT通讯协议,尤其注重标准制订,这样才能跟上loT的时代潮流。
声明:本文为 CSDN 博主马超(ID:beyondma)的原创文章,版权归作者所有。
扫描下方二维码,下载 CSDN App,查看博主精彩分享。

?热 文?推 荐?


?中国移动:部分 5G 手机可能有网连不上;iOS 13 出现严重漏洞;ReactOS 0.4.12发布 | 极客头条
?电信、联通合建 5G,将会碰出怎样的火花?
?看完这篇还不会kafka,我跪榴莲!

?谷歌称已实现量子霸权;iOS 捷径功能被诉侵权;Chrome 78 Beta 发布 | 极客头条

?使用Python对大脑成像数据进行可视化分析
?旷视张祥雨:高效轻量级深度模型的研究和实践 | ?AI ProCon 2019
?一文读懂分片基础原理, 数据分片, 跨分片交易, 区块链分片和缩放究竟是什么鬼?
?横扫阿里、滴滴、美团后,阿里程序媛整理出这份厚厚的面经!

点击阅读原文,即刻阅读《程序员大本营》最新期刊。

你点的每个“在看”,我都认真当成了喜欢

关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接