338 lines
10 KiB
Markdown
338 lines
10 KiB
Markdown
# 任务通信
|
||
|
||
XiUOS提供多种任务间通信机制,包括消息队列、信号量、互斥量与事件集。
|
||
|
||
## 消息队列
|
||
|
||
消息队列(message queue)提供可供多个任务读或写的消息缓冲区,其中消息指固定长度的任意数据块。消息队列的容量有限。当消息队列满时,向消息队列写入的任务会被挂起;当消息队列空时,从消息队列读取的任务会被挂起。
|
||
|
||
### 消息队列结构定义
|
||
|
||
```c
|
||
struct xs_MsgQueue
|
||
{
|
||
xs_uint16 id;
|
||
|
||
void *msg_buf;
|
||
xs_uint16 index;
|
||
xs_uint16 num_msgs;
|
||
xs_uint16 each_len;
|
||
xs_uint16 max_msgs;
|
||
|
||
XS_DOUBLE_LINKLIST send_pend_list;
|
||
XS_DOUBLE_LINKLIST recv_pend_list;
|
||
XS_DOUBLE_LINKLIST link;
|
||
};
|
||
```
|
||
|
||
| 成员 | 描述 |
|
||
| --- | --- |
|
||
| id | 消息队列ID,用于唯一标识一个消息队列 |
|
||
| msg_buf | 用于存储消息的缓冲区的首地址 |
|
||
| index | 当前缓冲区中第一个消息的序号 |
|
||
| num_msgs | 当前缓冲区中的消息数量 |
|
||
| each_len | 每条消息的大小,单位为字节 |
|
||
| max_msgs | 缓冲区中最多能存放的消息数量 |
|
||
| send_pend_list | 被挂起的发送任务链表 |
|
||
| recv_pend_list | 被挂起的接收任务链表 |
|
||
| link | 系统中所有消息队列构成的链表 |
|
||
|
||
### 消息队列函数接口
|
||
|
||
```c
|
||
xs_int32 xs_UserMsgQueueCreate(xs_uint16 msg_len, xs_uint16 max_msgs);
|
||
```
|
||
|
||
该函数用于创建一个消息队列。创建成功后,新的消息队列会被加入内核的消息队列管理链表,并返回该消息队列的ID,ID默认范围0-255,可配置。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| msg_len | 每条消息的长度,单位为字节 |
|
||
| max_msgs | 缓冲区中最多存放的消息数量 |
|
||
|
||
```c
|
||
void xs_UserMsgQueueDelete(xs_uint16 id);
|
||
```
|
||
|
||
该函数用于删除一个已创建的消息队列。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| id | 待删除的消息队列ID |
|
||
|
||
```c
|
||
xs_int32 xs_UserMsgQueueSend(xs_uint16 id, const void *msg, xs_uint16 size, xs_ticks_x wait_time);
|
||
```
|
||
|
||
该函数用于向消息队列发送一个消息。若消息发送成功则返回XS_EOK,若不成功(等待超时)则返回-XS_ETIMEOUT。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| id | 目标消息队列ID |
|
||
| msg | 消息数据首地址 |
|
||
| size | 消息长度 |
|
||
| wait_time | 等待时间上限,单位ticks;若为0,则不等待 |
|
||
|
||
```c
|
||
xs_int32 xs_UserMsgQueueRecv(xs_uint16 id, void *buf, xs_uint16 size, xs_ticks_x wait_time);
|
||
```
|
||
|
||
该函数用于从消息队列接收一个消息。若消息接收成功则返回XS_EOK,若不成功(等待超时)则返回-XS_ETIMEOUT。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| id | 来源消息队列ID |
|
||
| buf | 用于接收消息数据的缓冲区 |
|
||
| size | 缓冲区大小 |
|
||
| wait_time | 等待时间上限,单位ticks;若为0,则不等待 |
|
||
|
||
```c
|
||
xs_int32 xs_UserMsgQueueReinit(xs_uint16 id);
|
||
```
|
||
|
||
该函数用于将一个消息队列复位。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| id | 来源消息队列ID |
|
||
|
||
|
||
## 信号量
|
||
|
||
信号量(semaphore)具有一个给定的初值。任务可以获取或释放一个信号量。当任务获取信号量时信号量的值递减,释放信号量时值递增。当信号量值递减至0时,后续尝试获取信号量的任务会被挂起。每当一个已获取信号量的任务释放信号量时,内核会从信号量挂起队列上唤醒一个任务。信号量可以用于实现任务间的同步与互斥。
|
||
|
||
### 信号量结构定义
|
||
|
||
```c
|
||
struct xs_Semaphore
|
||
{
|
||
xs_uint16 id;
|
||
xs_uint16 value;
|
||
|
||
XS_DOUBLE_LINKLIST pend_list;
|
||
XS_DOUBLE_LINKLIST link;
|
||
};
|
||
```
|
||
|
||
| 成员 | 描述 |
|
||
| --- | --- |
|
||
| id | 信号量ID,用于唯一标识一个信号量 |
|
||
| value | 信号量的当前值 |
|
||
| pend_link | 挂起任务链表 |
|
||
| link | 系统中所有信号量构成的链表 |
|
||
|
||
### 信号量函数接口
|
||
|
||
```c
|
||
xs_int32 xs_UserSemaphoreCreate(xs_uint16 val);
|
||
```
|
||
|
||
该函数用于创建一个信号量。创建成功后,新的信号量会被加入内核的信号量管理链表,并返回该信号量的ID,ID默认范围0-255,可配置。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| val | 信号量的初值|
|
||
|
||
```c
|
||
void xs_UserSemaphoreDelete(xs_uint16 id);
|
||
```
|
||
|
||
该函数用于删除一个已创建的信号量。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| id | 待删除的信号量的ID |
|
||
|
||
```c
|
||
xs_int32 xs_UserSemaphoreObtain(xs_uint16 id, xs_ticks_x wait_time);
|
||
```
|
||
|
||
该函数用于获取一个信号量。若获取成功则返回XS_EOK,若不成功(等待超时)则返回-XS_ETIMEOUT。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| id | 欲获取的信号量的ID |
|
||
| wait_time | 等待时间上限,单位ticks;若为0,则不等待 |
|
||
|
||
```c
|
||
xs_int32 xs_UserSemaphoreAbandon(xs_uint16 id);
|
||
```
|
||
|
||
该函数用于释放一个信号量。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| id | 待释放的信号量的ID |
|
||
|
||
```c
|
||
xs_int32 xs_UserSemaphoreSetValue(xs_uint16 id, xs_uint16 val);
|
||
```
|
||
|
||
该函数用于将一个信号量的值进行重置。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| id | 来源消息队列ID |
|
||
| val | 重置的信号量的值 |
|
||
|
||
## 互斥量
|
||
|
||
互斥量(mutex)可以视作一个初值为1的信号量,同样有获取和释放操作。互斥量一般用于任务间的互斥。
|
||
|
||
### 互斥量结构定义
|
||
|
||
struct xs_Mutex
|
||
{
|
||
xs_uint16 id;
|
||
|
||
xs_uint8 origin_prio;
|
||
xs_uint8 recursive_cnt;
|
||
|
||
struct task_descriptor *holder;
|
||
|
||
XS_DOUBLE_LINKLIST pend_list;
|
||
XS_DOUBLE_LINKLIST link;
|
||
};
|
||
|
||
| 成员 | 描述 |
|
||
| --- | --- |
|
||
| id | 互斥量ID,用于唯一标识一个互斥量 |
|
||
| origin_prio | 持有互斥量的任务的原优先级,用于避免优先级反转 |
|
||
| recursive_cnt | 持有互斥量的任务获取互斥量的次数,用于实现递归锁 |
|
||
| holder | 持有互斥量的任务 |
|
||
| pend_list | 挂起任务链表 |
|
||
| link | 系统中所有互斥量构成的链表 |
|
||
|
||
### 互斥量函数接口
|
||
|
||
```c
|
||
xs_int32 xs_UserMutexCreate(void);
|
||
```
|
||
|
||
该函数用于创建一个互斥量。创建成功后,新的互斥量会被加入内核的互斥量管理链表,并返回该互斥量的ID,ID默认范围0-255,可配置。
|
||
|
||
```c
|
||
void xs_UserMutexDelete(xs_uint16 id);
|
||
```
|
||
|
||
该函数用于删除一个已创建的互斥量。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| id | 待删除的互斥量的ID |
|
||
|
||
```c
|
||
xs_int32 xs_UserMutexObtain(xs_uint16 id, xs_ticks_x wait_time);
|
||
```
|
||
|
||
该函数用于获取一个互斥量。若获取成功则返回XS_EOK,若不成功(等待超时)则返回-XS_ETIMEOUT。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| id | 欲获取的互斥量的ID |
|
||
| wait_time | 等待时间上限,单位ticks;若为0,则不等待 |
|
||
|
||
```c
|
||
xs_int32 xs_UserMutexAbandon(xs_uint16 id);
|
||
```
|
||
|
||
该函数用于释放一个互斥量。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| id | 待释放的互斥量的ID |
|
||
|
||
## 事件集
|
||
|
||
事件集(event set)允许用户定义一个事件集合,集合中的每个事件都可以被任务触发或等待。任务可以同时等待多个事件,此时等待触发的条件可以配置为AND或者OR:当等待触发条件配置为AND时,只有所有被等待的事件均被触发才视作等待结束;当等待触发条件配置为OR时,任意一个被等待的事件触发即视作等待结束。使用事件集可以实现多对多的任务间同步与互斥。
|
||
|
||
### 事件集结构定义
|
||
|
||
```c
|
||
#define XS_EVENT_AND (1 << 29)
|
||
#define XS_EVENT_OR (1 << 30)
|
||
#define XS_EVENT_AUTOCLEAN (1 << 31)
|
||
#define XS_EVENTS(x) (1 << x)
|
||
|
||
struct xs_event
|
||
{
|
||
xs_uint16 id;
|
||
xs_uint32 trigge_way;
|
||
|
||
XS_DOUBLE_LINKLIST pend_list;
|
||
XS_DOUBLE_LINKLIST link;
|
||
};
|
||
```
|
||
|
||
| 成员 | 描述 |
|
||
| --- | --- |
|
||
| id | 事件集ID,用于唯一标识一个事件集 |
|
||
| trigge_way | 高3位用于记录事件集属性(等待触发条件、是否自动清空),低29位用于表示至多29个事件 |
|
||
| pend_list | 等待任务链表 |
|
||
| link | 系统中所有事件集构成的链表 |
|
||
|
||
### 事件集函数接口
|
||
|
||
```c
|
||
xs_int32 xs_UserEventCreate(xs_uint32 options);
|
||
```
|
||
|
||
该函数用于创建一个事件集。options参数用于配置事件集的属性。可配置的属性有等待触发方式(XS_EVENT_AND或XS_EVENT_OR)及等待触发后是否自动清空其他已触发的事件(XS_EVENT_AUTOCLEAN)。创建成功后,新的事件集会被加入内核的事件集管理链表,并返回该事件集的ID,ID默认范围0-255,可配置。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| options | 事件集配置选项,须在XS_EVENT_AND及XS_EVENT_OR中指定其一,并可以按位或上XS_EVENT_AUTOCLEAN |
|
||
|
||
```c
|
||
void xs_UserEventDelete(xs_uint16 id);
|
||
```
|
||
|
||
该函数用于删除一个已创建的事件集。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| id | 待删除的事件集的ID |
|
||
|
||
```c
|
||
xs_int32 xs_UserEventTrigger(xs_uint16 id, xs_uint32 events);
|
||
```
|
||
|
||
该函数用于触发事件集中的一组事件。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| id | 事件集ID |
|
||
| events | 欲触发的事件,其中被置1的位标识被触发的事件 ,可以使用XS_EVENTS宏按位或发送事件类型|
|
||
|
||
```c
|
||
xs_int32 xs_UserEventProcess(xs_uint16 id, xs_uint32 events, xs_ticks_x wait_time);
|
||
```
|
||
|
||
该函数用于等待事件集中的一组事件。若等待成功则返回XS_EOK,此时若XS_EVENT_AUTOCLEAN被打开则事件集中所有已触发事件会被清空;若等待失败(超时)则返回-XS_ETIMEOUT。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| id | 事件集ID |
|
||
| events | 欲等待的事件,其中被置1的位标识被等待的事件,可以使用XS_EVENTS宏按位或接收事件类型|
|
||
| wait_time | 等待时间上限,单位ticks;若为0,则不等待 |
|
||
|
||
```c
|
||
xs_int32 xs_UserEventConfig(xs_uint16 id, xs_uint32 options);
|
||
```
|
||
|
||
该函数用于配置事件集中的一种事件类型。若等配置成功则返回XS_EOK,options参数用于配置事件集的属性。可配置的属性有等待触发方式(XS_EVENT_AND或XS_EVENT_OR)及等待触发后是否自动清空其他已触发的事件(XS_EVENT_AUTOCLEAN)。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| id | 事件集ID |
|
||
| options | 事件集配置选项,须在XS_EVENT_AND及XS_EVENT_OR中指定其一,并可以按位或上XS_EVENT_AUTOCLEAN |
|
||
|
||
```c
|
||
xs_int32 xs_UserEventReinit(xs_uint16 id);
|
||
```
|
||
|
||
该函数用于将一个事件的值进行重置。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| id | 来源消息队列ID | |