一,前言
不识庐山真面目,只缘生在此山中。光看细节代码不了解架构或者需求的话,很多东西都看不全面,而我的目的主要是了解设计思想为我所用,而不是了解c语言编程技巧。所以先中需求下手,然后再去看代码。主要是用来做闭环验证,验证我理解的需求是否正确而已,顺便看看c语言去实现这样的需求中用到的结构体及其算法的设计。
二,threadx OS通信机制
- 信号灯(量)
主要用来做任务间同步或资源保护。主要包括二进制信号灯和计数信号灯。
执行获取操作会将信号灯数量减一。 如果信号灯为 0,获取操作不会成功。 获取操作的逆操作是放置操作。 该操作会将信号灯数量加一。 - 互斥量
主要用来做共享资源保护。
互斥实质上是二进制信号灯。 - 事件集
主要用来通知事件。 - 消息队列
主要用来传递信息。
消息队列中可以驻留一个或多个消息。比如FIFO或LIFO方式。 - 邮箱
主要用来传递信息。
保留单个消息的消息队列通常称为邮箱。新的消息会覆盖原有消息。
以上说明了应用也说明了各类通信机制的区别点。
三,计数信号灯的源码分析
所有这些任务间通信机制的代码实现都是在关闭中断的情况下执行的。接着这些通信机制中的代码应该是短小的。其实光看上面的需求也确实是比较简单的代码。
比如获取信号的函数_txe_semaphore_get->_tx_semaphore_get
“执行获取操作会将信号灯数量减一。 如果信号灯为 0,获取操作不会成功。”
![](https://img.haomeiwen.com/i12010880/d6b4060d7a1e73df.png)
信号灯结构体
从结构体来看主要是id,名称,计数值和挂起列表。然后就是标配的双链表。最后是扩展的调试信息。
typedef struct TX_SEMAPHORE_STRUCT
{
/* Define the semaphore ID used for error checking. */
ULONG tx_semaphore_id;
/* Define the semaphore's name. */
CHAR *tx_semaphore_name;
/* Define the actual semaphore count. A zero means that no semaphore
instance is available. */
ULONG tx_semaphore_count;
/* Define the semaphore suspension list head along with a count of
how many threads are suspended. */
struct TX_THREAD_STRUCT
*tx_semaphore_suspension_list;
UINT tx_semaphore_suspended_count;
/* Define the created list next and previous pointers. */
struct TX_SEMAPHORE_STRUCT
*tx_semaphore_created_next,
*tx_semaphore_created_previous;
#ifdef TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO
/* Define the number of semaphore puts. */
ULONG tx_semaphore_performance_put_count;
/* Define the number of semaphore gets. */
ULONG tx_semaphore_performance_get_count;
/* Define the number of semaphore suspensions. */
ULONG tx_semaphore_performance_suspension_count;
/* Define the number of semaphore timeouts. */
ULONG tx_semaphore_performance_timeout_count;
#endif
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
/* Define the application callback routine used to notify the application when
the a semaphore is put. */
VOID (*tx_semaphore_put_notify)(struct TX_SEMAPHORE_STRUCT *semaphore_ptr);
#endif
/* Define the port extension in the semaphore control block. This
is typically defined to whitespace in tx_port.h. */
TX_SEMAPHORE_EXTENSION
} TX_SEMAPHORE;
从结构和代码的设计有2点值得我学习
- 宏定义开关添加调试信息。我设计代码一般不会考虑到调试信息的设计。但是加个宏开关就可以方便的添加调试信息了。
- 结构体定义中用宏定义
TX_SEMAPHORE_EXTENSION
,便于扩展,若不需要的时候则设置为空。比如可以添加user callback函数支持扩展。钩子函数一添加,就能有回调函数功能了。当然此处按注释可以看出不是callback函数。而且上面的callback函数用的是宏开关方式。
四,小结
所以c代码都是数据结构加算法,OS的通信机制就是按需求实现c代码即可。OS通信机制代码为什么没有设计的很复杂,原因就是它是在关全局中断中执行的。另外,我想到一个问题,就是通信机制能否可以将5类结构体抽象再合并为仅1个结构体,或再创造发明其它类的通信机制。我理解是可行的。只是拆分结构体后,从功能角度来说颗粒度就变小了,逻辑更简单,代码执行效率更高了,这才更符合RTOS的时时性。不过我以前看到过一个事件通知的描述好像就是好几个功能的合集,这不清楚它代码是如何优化性能的。
网友评论