diff --git a/docs/.vuepress/sidebar.js b/docs/.vuepress/sidebar.js index 3517cab..93ea43b 100755 --- a/docs/.vuepress/sidebar.js +++ b/docs/.vuepress/sidebar.js @@ -3,13 +3,10 @@ const sidebar = { '/doc/intro', ], 'kernel': [ - '/doc/kernel/task', + '/doc/kernel/task/', '/doc/kernel/mm', - '/doc/kernel/synchron', - '/doc/kernel/threadcommunication', '/doc/kernel/int', - '/doc/kernel/tmr', - '/doc/kernel/task' + '/doc/kernel/tmr' ], 'component': [ '/doc/component/fs', diff --git a/docs/doc/ipc.md b/docs/doc/ipc.md new file mode 100644 index 0000000..38ae26a --- /dev/null +++ b/docs/doc/ipc.md @@ -0,0 +1,338 @@ +# 任务通信 + +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 | \ No newline at end of file diff --git a/docs/doc/kernel/README.md b/docs/doc/kernel/README.md index 473e771..3338434 100644 --- a/docs/doc/kernel/README.md +++ b/docs/doc/kernel/README.md @@ -2,14 +2,10 @@ --- -- [线程管理](/doc/kernel/task.md) +- [任务管理](/doc/kernel/task/) - [内存管理](/doc/kernel/mm.md) -- [线程间同步](/doc/kernel/synchron.md) - -- [线程间通信](/doc/kernel/threadcommunication.md) - -- [终端机制](/doc/kernel/int.md) +- [中断机制](/doc/kernel/int.md) - [节拍机制](/doc/kernel/tmr.md) \ No newline at end of file diff --git a/docs/doc/kernel/int.md b/docs/doc/kernel/int.md index 1d1b790..ed2d403 100644 --- a/docs/doc/kernel/int.md +++ b/docs/doc/kernel/int.md @@ -1 +1 @@ -# 终端机制 \ No newline at end of file +# 中断机制 \ No newline at end of file diff --git a/docs/doc/kernel/ipc.md b/docs/doc/kernel/ipc.md new file mode 100644 index 0000000..38ae26a --- /dev/null +++ b/docs/doc/kernel/ipc.md @@ -0,0 +1,338 @@ +# 任务通信 + +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 | \ No newline at end of file diff --git a/docs/doc/kernel/task.md b/docs/doc/kernel/task.md old mode 100755 new mode 100644 index dfc369a..ad4ca79 --- a/docs/doc/kernel/task.md +++ b/docs/doc/kernel/task.md @@ -1 +1,174 @@ -# 线程管理 +# 任务管理 + +任务(task)是XiUOS中处理器使用权分配的最小单位。每个任务有自己的程序栈与寄存器上下文,在多处理器平台上可以互不干扰地同时运行,但单个处理器上任意时刻只能有一个任务在运行。用户可以使用XiUOS提供的接口创建任意数量的任务。内核会对系统中的所有任务按照一定策略(抢占式优先级或先来先服务)进行调度,以最大限度地利用处理器资源。用户可以使用XiUOS提供的接口创建任意数量的任务。 + +## 任务状态 + +系统中的任务在任意时刻都处于就绪(ready)、运行(running)、阻塞/挂起(suspend)、退出(quit)四种状态之一。状态之间的变化关系如下图所示。 + +![task_status](task_status.png) + +任务在创建完成后会进入就绪状态并被加入就绪队列等待内核调度。当任务被调度开始运行时,任务会进入运行状态。若任务在运行过程中被更高优先级的任务抢占,则被强占的任务会回到就绪队列并再次进入就绪状态。当任务在运行过程中申请资源失败时,任务会被挂起并进入挂起状态,并在所申请资源能够被满足时回到就绪状态。当任务执行完成,即从入口函数返回时,会进入终止状态,并由内核回收其相关资源。 + +## 任务调度 + +任务调度即从系统就绪队列中按一定策略选择任务,使其进入运行状态的过程。XiUOS支持以下调度方式: + +* 抢占式优先级调度:在创建任务时可以指定任务的优先级,内核总是选取就绪队列中优先级最高的任务。当新创建的任务优先级高于正在运行的任务的优先级时,当前运行的任务会被抢占。若就绪队列中最高优先级任务有多个,则这些任务会按时间片轮转交替运行。 +* 先来先服务(FIFO)调度:任务按照被创建的顺序依次被执行。当一个任务运行完成后,系统才会让下一个任务开始运行。 +* 时间片轮转(RR)调度:任务按照分配的时间片执行,时间片结束,调度一个新的就绪任务执行,当前任务重新就绪,等待下一次的调度。 + +## 任务结构定义 + +每个任务在内核中由一个task_descriptor结构表示,二者一一对应。 + +```c +struct task_descriptor +{ + void *stack_pointer; + + struct dync_sched_member dync_sched_member_x; + + struct t_baseinfo t_baseinfo_x; + + #ifdef XS_USING_SMP + struct smp_info smp_info_x; + #endif + +#if defined(XS_USING_EVENT) + xs_uint32 event_ctrl1:3; + xs_uint32 event_ctrl2:29; +#endif + + xs_err_t error; + XS_DOUBLE_LINKLIST link; +}; +``` + +其中stack_pointer成员表示该任务的栈的起始地址,dync_sched_member_x成员包含与任务调度相关的信息,t_baseinfo_x包含任务的基本信息,smp_info_x包含与多处理器相关的信息,event_ctrl1/event_ctrl2用于实现事件集机制(见任务间通信部分文档),error为任务调用内核接口时最近的错误码,link用于将系统中的所有任务组织成一个双链表。各复合成员的详细定义如下: + +```c +struct task_baseinfo { + char name[XS_NAME_MAX]; + void *func_entry; + void *func_param; + xs_uint32 stack_size; + xs_uint8 origin_prio; +}; +``` + +struct task_baseinfo结构记录了任务的基本属性,包括任务的名称(name)、入口函数和参数(func_entry、func_param)、栈大小(stack_size)、优先级(origin_prio)。 + +```c +struct dync_sched_member { + xs_uint8 stat; + xs_uint8 advance_cnt; + xs_uint8 cur_prio; + xs_ubase origin_timeslice; + xs_ubase rest_timeslice; +#ifdef XS_USING_TASK_ISOLATION + xs_uint8 isolation_flag; + void *isolation; +#endif + union { + XS_DOUBLE_LINKLIST sched_link; + XS_AVL sched_avl; + } + XS_DOUBLE_LINKLIST pend_link; + xs_Timer_t task_timer; +}; + +#define XS_SUSPEND ((1) << (0)) +#define XS_READY ((1) << (1)) +#define XS_RUNNING ((1) << (2)) +#define XS_QUIT ((1) << (3)) +``` + +struct dync_sched_member结构的成员用于记录与调度相关的信息。stat表示任务的当前状态,可以为挂起(XS_SUSPEND)、就绪(XS_READY)、运行(XS_RUNNING)或退出(XS_QUIT)。advance_cnt表示在配置成短作业预先调度时优先处理的时间片周期个数。cur_prio表示任务当前的优先级:为防止出现优先级反转,该优先级可以高于任务创建时配置的优先级。origin_timeslice表示在时间片轮转调度中该任务每次运行的时间片。地址空间隔离信息(isolation_flag变量和指针isolation)。sched_link、sched_avl构成的联合体为就绪队列节点,XiUOS中就绪队列可以配置为双链表(sched_link)或AVL树(sched_avl)。pend_link为任务挂起时使用的等待队列节点。task_timer用于任务睡眠的计时。 + +```c +struct smp_info { + xs_uint8 combined_coreid; + xs_uint8 runing_coreid; +}; +``` + +struct smp_info结构包含多处理器相关的信息,其成员分别表示该任务绑定的CPU ID与正在运行的CPU ID。 + +## 任务函数接口 + +```c +struct xs_utask +{ + char name[XS_NAME_MAX]; + void *func_entry; + void *func_param; + xs_uint32 stack_size; + xs_uint8 prio; +}; +typedef struct xs_utask struct xs_utask; + +struct task_descriptor* xs_UserTaskCreate(xs_utask_x task); +``` + +该函数用于用户态创建一个任务。任务的各个属性由一个struct xs_utask结构表示,包括任务的名称、入口函数及参数、栈大小和优先级,在调用该函数时需要传入该结构的实例用于配置任务。任务创建成功后,内核会为其分配指定大小的栈及其他结构(如struct task_descriptor)结构,并返回任务描述符指针。 + +| 参数 | 描述 | +| --- | --- | +| task | 任务配置属性 | + +```c +xs_int32 xs_UserTaskDelete(struct task_descriptor task); +``` + +该函数用于删除一个任务,强制使其进入退出状态。若删除成功则返回XS_EOK,若失败则返回-XS_ERROR。 + +| 参数 | 描述 | +| --- | --- | +| task| 待删除的任务描述符 | + +```c +xs_int32 xs_UserTaskCoreCombine(struct task_descriptor task, xs_uint8 coreid); +``` + +该函数用于将任务绑定至指定的处理器上。若绑定成功则返回XS_EOK,若失败则返回-XS_ERROR。 + +| 参数 | 描述 | +| --- | --- | +| task_id | 待绑定的任务描述符 | +| coreid | 带绑定的处理器ID | + +```c +xs_int32 xs_UserTaskCoreUncombine(struct task_descriptor task); +``` + +该函数用于解除任务与处理器的绑定。若解除成功则返回XS_EOK,若失败则返回-XS_ERROR。 + +| 参数 | 描述 | +| --- | --- | +| task | 待解除绑定的任务描述符 | + +```c +xs_int32 xs_UserTaskDelay(xs_ticks_x ticks); +``` + +该函数用于将当前任务挂起一定时间,单位为tick。挂起时间结束后,任务会进入就绪状态,可以继续被调度。 + +| 参数 | 描述 | +| --- | --- | +| ticks | 任务挂起时间,单位为tick | + +```c +struct task_descriptor* xs_UserTaskSearch(char *name) +``` + +该函数用于从任务名称获取任务描述符。 + +| 参数 | 描述 | +| --- | --- | +| name | 任务名称 | + +## 使用场景 + +* 在多处理器设备上,多个任务可以并行运行,从而提高处理器的利用率。 +* 在一些中断驱动的应用中,如果中断需要处理的工作过于复杂,则可以创建一个任务专门用于处理相关工作,从而改善中断延迟。 \ No newline at end of file diff --git a/docs/doc/kernel/task/README.md b/docs/doc/kernel/task/README.md new file mode 100644 index 0000000..1a1de66 --- /dev/null +++ b/docs/doc/kernel/task/README.md @@ -0,0 +1,8 @@ +# 任务管理 + +--- + +- [线程管理](/doc/kernel/task.md) + +- [线程ipc](/doc/kernel/ipc.md) + diff --git a/docs/doc/task.md b/docs/doc/task.md new file mode 100644 index 0000000..ad4ca79 --- /dev/null +++ b/docs/doc/task.md @@ -0,0 +1,174 @@ +# 任务管理 + +任务(task)是XiUOS中处理器使用权分配的最小单位。每个任务有自己的程序栈与寄存器上下文,在多处理器平台上可以互不干扰地同时运行,但单个处理器上任意时刻只能有一个任务在运行。用户可以使用XiUOS提供的接口创建任意数量的任务。内核会对系统中的所有任务按照一定策略(抢占式优先级或先来先服务)进行调度,以最大限度地利用处理器资源。用户可以使用XiUOS提供的接口创建任意数量的任务。 + +## 任务状态 + +系统中的任务在任意时刻都处于就绪(ready)、运行(running)、阻塞/挂起(suspend)、退出(quit)四种状态之一。状态之间的变化关系如下图所示。 + +![task_status](task_status.png) + +任务在创建完成后会进入就绪状态并被加入就绪队列等待内核调度。当任务被调度开始运行时,任务会进入运行状态。若任务在运行过程中被更高优先级的任务抢占,则被强占的任务会回到就绪队列并再次进入就绪状态。当任务在运行过程中申请资源失败时,任务会被挂起并进入挂起状态,并在所申请资源能够被满足时回到就绪状态。当任务执行完成,即从入口函数返回时,会进入终止状态,并由内核回收其相关资源。 + +## 任务调度 + +任务调度即从系统就绪队列中按一定策略选择任务,使其进入运行状态的过程。XiUOS支持以下调度方式: + +* 抢占式优先级调度:在创建任务时可以指定任务的优先级,内核总是选取就绪队列中优先级最高的任务。当新创建的任务优先级高于正在运行的任务的优先级时,当前运行的任务会被抢占。若就绪队列中最高优先级任务有多个,则这些任务会按时间片轮转交替运行。 +* 先来先服务(FIFO)调度:任务按照被创建的顺序依次被执行。当一个任务运行完成后,系统才会让下一个任务开始运行。 +* 时间片轮转(RR)调度:任务按照分配的时间片执行,时间片结束,调度一个新的就绪任务执行,当前任务重新就绪,等待下一次的调度。 + +## 任务结构定义 + +每个任务在内核中由一个task_descriptor结构表示,二者一一对应。 + +```c +struct task_descriptor +{ + void *stack_pointer; + + struct dync_sched_member dync_sched_member_x; + + struct t_baseinfo t_baseinfo_x; + + #ifdef XS_USING_SMP + struct smp_info smp_info_x; + #endif + +#if defined(XS_USING_EVENT) + xs_uint32 event_ctrl1:3; + xs_uint32 event_ctrl2:29; +#endif + + xs_err_t error; + XS_DOUBLE_LINKLIST link; +}; +``` + +其中stack_pointer成员表示该任务的栈的起始地址,dync_sched_member_x成员包含与任务调度相关的信息,t_baseinfo_x包含任务的基本信息,smp_info_x包含与多处理器相关的信息,event_ctrl1/event_ctrl2用于实现事件集机制(见任务间通信部分文档),error为任务调用内核接口时最近的错误码,link用于将系统中的所有任务组织成一个双链表。各复合成员的详细定义如下: + +```c +struct task_baseinfo { + char name[XS_NAME_MAX]; + void *func_entry; + void *func_param; + xs_uint32 stack_size; + xs_uint8 origin_prio; +}; +``` + +struct task_baseinfo结构记录了任务的基本属性,包括任务的名称(name)、入口函数和参数(func_entry、func_param)、栈大小(stack_size)、优先级(origin_prio)。 + +```c +struct dync_sched_member { + xs_uint8 stat; + xs_uint8 advance_cnt; + xs_uint8 cur_prio; + xs_ubase origin_timeslice; + xs_ubase rest_timeslice; +#ifdef XS_USING_TASK_ISOLATION + xs_uint8 isolation_flag; + void *isolation; +#endif + union { + XS_DOUBLE_LINKLIST sched_link; + XS_AVL sched_avl; + } + XS_DOUBLE_LINKLIST pend_link; + xs_Timer_t task_timer; +}; + +#define XS_SUSPEND ((1) << (0)) +#define XS_READY ((1) << (1)) +#define XS_RUNNING ((1) << (2)) +#define XS_QUIT ((1) << (3)) +``` + +struct dync_sched_member结构的成员用于记录与调度相关的信息。stat表示任务的当前状态,可以为挂起(XS_SUSPEND)、就绪(XS_READY)、运行(XS_RUNNING)或退出(XS_QUIT)。advance_cnt表示在配置成短作业预先调度时优先处理的时间片周期个数。cur_prio表示任务当前的优先级:为防止出现优先级反转,该优先级可以高于任务创建时配置的优先级。origin_timeslice表示在时间片轮转调度中该任务每次运行的时间片。地址空间隔离信息(isolation_flag变量和指针isolation)。sched_link、sched_avl构成的联合体为就绪队列节点,XiUOS中就绪队列可以配置为双链表(sched_link)或AVL树(sched_avl)。pend_link为任务挂起时使用的等待队列节点。task_timer用于任务睡眠的计时。 + +```c +struct smp_info { + xs_uint8 combined_coreid; + xs_uint8 runing_coreid; +}; +``` + +struct smp_info结构包含多处理器相关的信息,其成员分别表示该任务绑定的CPU ID与正在运行的CPU ID。 + +## 任务函数接口 + +```c +struct xs_utask +{ + char name[XS_NAME_MAX]; + void *func_entry; + void *func_param; + xs_uint32 stack_size; + xs_uint8 prio; +}; +typedef struct xs_utask struct xs_utask; + +struct task_descriptor* xs_UserTaskCreate(xs_utask_x task); +``` + +该函数用于用户态创建一个任务。任务的各个属性由一个struct xs_utask结构表示,包括任务的名称、入口函数及参数、栈大小和优先级,在调用该函数时需要传入该结构的实例用于配置任务。任务创建成功后,内核会为其分配指定大小的栈及其他结构(如struct task_descriptor)结构,并返回任务描述符指针。 + +| 参数 | 描述 | +| --- | --- | +| task | 任务配置属性 | + +```c +xs_int32 xs_UserTaskDelete(struct task_descriptor task); +``` + +该函数用于删除一个任务,强制使其进入退出状态。若删除成功则返回XS_EOK,若失败则返回-XS_ERROR。 + +| 参数 | 描述 | +| --- | --- | +| task| 待删除的任务描述符 | + +```c +xs_int32 xs_UserTaskCoreCombine(struct task_descriptor task, xs_uint8 coreid); +``` + +该函数用于将任务绑定至指定的处理器上。若绑定成功则返回XS_EOK,若失败则返回-XS_ERROR。 + +| 参数 | 描述 | +| --- | --- | +| task_id | 待绑定的任务描述符 | +| coreid | 带绑定的处理器ID | + +```c +xs_int32 xs_UserTaskCoreUncombine(struct task_descriptor task); +``` + +该函数用于解除任务与处理器的绑定。若解除成功则返回XS_EOK,若失败则返回-XS_ERROR。 + +| 参数 | 描述 | +| --- | --- | +| task | 待解除绑定的任务描述符 | + +```c +xs_int32 xs_UserTaskDelay(xs_ticks_x ticks); +``` + +该函数用于将当前任务挂起一定时间,单位为tick。挂起时间结束后,任务会进入就绪状态,可以继续被调度。 + +| 参数 | 描述 | +| --- | --- | +| ticks | 任务挂起时间,单位为tick | + +```c +struct task_descriptor* xs_UserTaskSearch(char *name) +``` + +该函数用于从任务名称获取任务描述符。 + +| 参数 | 描述 | +| --- | --- | +| name | 任务名称 | + +## 使用场景 + +* 在多处理器设备上,多个任务可以并行运行,从而提高处理器的利用率。 +* 在一些中断驱动的应用中,如果中断需要处理的工作过于复杂,则可以创建一个任务专门用于处理相关工作,从而改善中断延迟。 \ No newline at end of file