From 74572d20fe9e154d239701c5ec673e34596d5802 Mon Sep 17 00:00:00 2001 From: daishengdong Date: Thu, 14 Nov 2019 19:27:36 +0800 Subject: [PATCH] =?UTF-8?q?refresh=20=E5=BC=80=E5=8F=91=E6=8C=87=E5=8D=97.?= =?UTF-8?q?pdf?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add new interface develop guide and sample code --- ...47\345\223\201\347\256\200\344\273\213.md" | 0 ...7_\345\205\215\350\264\271\347\211\210.md" | 0 ...53\351\200\237\345\205\245\351\227\250.md" | 0 ...00\345\217\221\346\214\207\345\215\227.md" | 956 ++++++++++++++---- ...entOS tiny SDK\346\226\207\346\241\243.md" | 326 ++++++ ...70\350\247\201\351\227\256\351\242\230.md" | 0 ...y \350\257\215\346\261\207\350\241\250.md" | 0 ...00\345\217\221\346\214\207\345\215\227.md" | 0 ...md => TencentOS tiny porting guide gcc.md} | 0 ...md => TencentOS tiny porting guide iar.md} | 0 ...d => TencentOS tiny porting guide keil.md} | 0 ...entOS tiny porting(MacOS_STM32CubeIDE).md} | 0 ...56\345\275\225\350\257\264\346\230\216.md" | 0 ...5\351\227\250\346\214\207\345\215\227.pdf" | Bin doc/code/2.3.4 completion/main.c | 39 + doc/code/2.3.5 countdownlatch/main.c | 61 ++ .../main.c | 45 +- doc/code/2.3.7 mail queue/main.c | 113 +++ doc/code/2.3.8 priority message queue/main.c | 62 ++ doc/code/2.3.9 priority mail queue/main.c | 73 ++ doc/code/2.8.1 msg_queue/main.c | 123 --- doc/code/2.8.1 ring queue/main.c | 76 ++ .../{2.8.2 fifo => 2.8.2 char fifo}/main.c | 6 +- doc/code/2.8.4 priority queue/main.c | 78 ++ kernel/core/include/tos_completion.h | 2 - net/at/include/tos_at.h | 42 +- 26 files changed, 1614 insertions(+), 388 deletions(-) rename "doc/1.TencentOS tiny\344\272\247\345\223\201\347\256\200\344\273\213.md" => "doc/1.TencentOS tiny \344\272\247\345\223\201\347\256\200\344\273\213.md" (100%) rename "doc/2.TencentOS tiny\350\264\255\344\271\260\346\214\207\345\215\227_\345\205\215\350\264\271\347\211\210.md" => "doc/2.TencentOS tiny \350\264\255\344\271\260\346\214\207\345\215\227_\345\205\215\350\264\271\347\211\210.md" (100%) rename "doc/3.TencentOS tiny\345\277\253\351\200\237\345\205\245\351\227\250.md" => "doc/3.TencentOS tiny \345\277\253\351\200\237\345\205\245\351\227\250.md" (100%) rename "doc/4.TencentOS-tiny\345\274\200\345\217\221\346\214\207\345\215\227.md" => "doc/4.TencentOS tiny \345\274\200\345\217\221\346\214\207\345\215\227.md" (68%) rename "doc/5.TencentOS-tiny-SDK\346\226\207\346\241\243.md" => "doc/5.TencentOS tiny SDK\346\226\207\346\241\243.md" (93%) rename "doc/6.TencentOS tiny\345\270\270\350\247\201\351\227\256\351\242\230.md" => "doc/6.TencentOS tiny \345\270\270\350\247\201\351\227\256\351\242\230.md" (100%) rename "doc/7.TencentOS tiny\350\257\215\346\261\207\350\241\250.md" => "doc/7.TencentOS tiny \350\257\215\346\261\207\350\241\250.md" (100%) rename "doc/8.TencentOS-tiny\345\257\271\346\216\245\350\205\276\350\256\257\344\272\221IoTHub\345\274\200\345\217\221\346\214\207\345\215\227.md" => "doc/8.TencentOS tiny \345\257\271\346\216\245\350\205\276\350\256\257\344\272\221IoTHub\345\274\200\345\217\221\346\214\207\345\215\227.md" (100%) rename doc/{TencentOS-tiny-porting-guide-gcc.md => TencentOS tiny porting guide gcc.md} (100%) rename doc/{TencentOS-tiny-porting-guide-iar.md => TencentOS tiny porting guide iar.md} (100%) rename doc/{TencentOS-tiny-porting-guide-keil.md => TencentOS tiny porting guide keil.md} (100%) rename doc/{TencentOS-tiny-porting(MacOS_STM32CubeIDE).md => TencentOS tiny porting(MacOS_STM32CubeIDE).md} (100%) rename "doc/TencentOS-tiny-\344\273\243\347\240\201\347\233\256\345\275\225\350\257\264\346\230\216.md" => "doc/TencentOS tiny \344\273\243\347\240\201\347\233\256\345\275\225\350\257\264\346\230\216.md" (100%) rename "doc/TencentOS-tiny\345\256\232\345\210\266\345\274\200\345\217\221\346\235\277\345\205\245\351\227\250\346\214\207\345\215\227.pdf" => "doc/TencentOS tiny \345\256\232\345\210\266\345\274\200\345\217\221\346\235\277\345\205\245\351\227\250\346\214\207\345\215\227.pdf" (100%) create mode 100644 doc/code/2.3.4 completion/main.c create mode 100644 doc/code/2.3.5 countdownlatch/main.c rename doc/code/{2.3.4 queue => 2.3.6 message queue}/main.c (57%) create mode 100644 doc/code/2.3.7 mail queue/main.c create mode 100644 doc/code/2.3.8 priority message queue/main.c create mode 100644 doc/code/2.3.9 priority mail queue/main.c delete mode 100644 doc/code/2.8.1 msg_queue/main.c create mode 100644 doc/code/2.8.1 ring queue/main.c rename doc/code/{2.8.2 fifo => 2.8.2 char fifo}/main.c (95%) create mode 100644 doc/code/2.8.4 priority queue/main.c diff --git "a/doc/1.TencentOS tiny\344\272\247\345\223\201\347\256\200\344\273\213.md" "b/doc/1.TencentOS tiny \344\272\247\345\223\201\347\256\200\344\273\213.md" similarity index 100% rename from "doc/1.TencentOS tiny\344\272\247\345\223\201\347\256\200\344\273\213.md" rename to "doc/1.TencentOS tiny \344\272\247\345\223\201\347\256\200\344\273\213.md" diff --git "a/doc/2.TencentOS tiny\350\264\255\344\271\260\346\214\207\345\215\227_\345\205\215\350\264\271\347\211\210.md" "b/doc/2.TencentOS tiny \350\264\255\344\271\260\346\214\207\345\215\227_\345\205\215\350\264\271\347\211\210.md" similarity index 100% rename from "doc/2.TencentOS tiny\350\264\255\344\271\260\346\214\207\345\215\227_\345\205\215\350\264\271\347\211\210.md" rename to "doc/2.TencentOS tiny \350\264\255\344\271\260\346\214\207\345\215\227_\345\205\215\350\264\271\347\211\210.md" diff --git "a/doc/3.TencentOS tiny\345\277\253\351\200\237\345\205\245\351\227\250.md" "b/doc/3.TencentOS tiny \345\277\253\351\200\237\345\205\245\351\227\250.md" similarity index 100% rename from "doc/3.TencentOS tiny\345\277\253\351\200\237\345\205\245\351\227\250.md" rename to "doc/3.TencentOS tiny \345\277\253\351\200\237\345\205\245\351\227\250.md" diff --git "a/doc/4.TencentOS-tiny\345\274\200\345\217\221\346\214\207\345\215\227.md" "b/doc/4.TencentOS tiny \345\274\200\345\217\221\346\214\207\345\215\227.md" similarity index 68% rename from "doc/4.TencentOS-tiny\345\274\200\345\217\221\346\214\207\345\215\227.md" rename to "doc/4.TencentOS tiny \345\274\200\345\217\221\346\214\207\345\215\227.md" index d0fb364b..4973bc24 100644 --- "a/doc/4.TencentOS-tiny\345\274\200\345\217\221\346\214\207\345\215\227.md" +++ "b/doc/4.TencentOS tiny \345\274\200\345\217\221\346\214\207\345\215\227.md" @@ -769,27 +769,191 @@ int main(void) [实例代码](./code/2.3.3 event/main.c) -#### 2.3.4 队列 +#### 2.3.4 完成量 ##### 概述 -队列提供了一种任务间实现同步和数据传递的机制。事件只能用于任务间传递某类“事件”是否发生的信号,无法传递更为复杂的数据,队列弥补了事件的这一不足,可以在任务间传递不定长度的消息。 +完成量是一种简单的任务间通信机制,用以在任务间同步某一事件是否已“完成”的信息。 ##### API讲解 ##### 编程实例 -1、在tos_config.h中,配置队列组件开关TOS_CFG_QUEUE_EN: +1、在tos_config.h中,配置完成量组件开关TOS_CFG_COMPLETION_EN: -`#define TOS_CFG_QUEUE_EN 1u` +`#define TOS_CFG_COMPLETION_EN 1u` -2、在tos_config.h中,配置消息队列组件开关TOS_CFG_MSG_EN: +2、编写main.c示例代码: -`#define TOS_CFG_MSG_EN 1u` +```c +/* + 这个例子里创建了两个任务,一个任务task_wait等待完成量完成,另一个任务负责触发完成量(让完成量完成) + */ -3、编写main.c示例代码: +#include "tos.h" +#include "mcu_init.h" + +#define STK_SIZE_TASK_WAIT 512 +#define STK_SIZE_TASK_TRIGGER 512 + +k_stack_t stack_task_wait[STK_SIZE_TASK_WAIT]; +k_stack_t stack_task_trigger[STK_SIZE_TASK_TRIGGER]; + +k_task_t task_wait; +k_task_t task_trigger; + +k_completion_t completion; + +void entry_task_wait(void *arg) +{ + printf("wait: I won't go further until someone do the trigger(make it 'complete')\n"); + tos_completion_pend(&completion); + printf("wait: someone has made it complete, so I'm here\n"); +} + +void entry_task_trigger(void *arg) +{ + printf("trigger: I'm the one who make complete, anyone waitting for the complete won't go further until I do the trigger\n"); + tos_completion_post(&completion); + printf("trigger: I have done the completion\n"); +} + +int main(void) +{ + board_init(); + tos_knl_init(); + tos_completion_create(&completion); + (void)tos_task_create(&task_wait, "wait", entry_task_wait, NULL, + 3, stack_task_wait, STK_SIZE_TASK_WAIT, 0); + (void)tos_task_create(&task_trigger, "trigger", entry_task_trigger, NULL, + 4, stack_task_trigger, STK_SIZE_TASK_TRIGGER, 0); + tos_knl_start(); +} +``` + +##### 运行效果 + +> wait: I won't go further until someone do the trigger(make it 'complete') +> trigger: I'm the one who make complete, anyone waitting for the complete won't go further until I do the trigger +> wait: someone make it complete, so I'm here +> trigger: I have done the completion + +[实例代码](./code/2.3.4 completion/main.c) + +#### 2.3.5 计数锁 + +##### 概述 + +计数锁提供了一种“计数信息”同步的概念,计数锁创建的时候会指定一个计数值,每当有任务执行tos_countdownlatch_post时,该计数锁的计数值减一,直到计数锁的计数值为零时,等待此计数锁的任务才会被唤醒。 + +##### API讲解 + +##### 编程实例 + +1、在tos_config.h中,配置队列组件开关TOS_CFG_COUNTDOWNLATCH_EN: + +`#define TOS_CFG_COUNTDOWNLATCH_EN 1u` + +2、编写main.c示例代码: + +```c +/* + 假设有这样的业务场景,共有三个勇士,此三个勇士分头去寻找三个武器的碎片,只有这三个勇士都找到碎片后,法师才能将三个碎片合成为武器。用代码看具体如何使用计数锁来完成这个模型。 + */ + +#include "tos.h" +#include "mcu_init.h" + +#define STK_SIZE_TASK_WIZARD 512 +#define STK_SIZE_TASK_WARRIOR 512 + +k_stack_t stack_task_wizard[STK_SIZE_TASK_WIZARD]; +k_stack_t stack_task_warrior_0[STK_SIZE_TASK_WARRIOR]; +k_stack_t stack_task_warrior_1[STK_SIZE_TASK_WARRIOR]; +k_stack_t stack_task_warrior_2[STK_SIZE_TASK_WARRIOR]; + +k_task_t task_wizard; +k_task_t task_warrior_0; +k_task_t task_warrior_1; +k_task_t task_warrior_2; + +k_countdownlatch_t countdownlatch; + +void entry_task_warrior_0(void *arg) +{ + printf("warrior 0: I have done my job\n"); + tos_countdownlatch_post(&countdownlatch); +} + +void entry_task_warrior_1(void *arg) +{ + printf("warrior 1: I have done my job\n"); + tos_countdownlatch_post(&countdownlatch); +} + +void entry_task_warrior_2(void *arg) +{ + printf("warrior 2: I have done my job\n"); + tos_countdownlatch_post(&countdownlatch); +} + +void entry_task_wizard(void *arg) +{ + printf("wizard: I will set 3 warriors to find the fragments\n"); + tos_countdownlatch_create(&countdownlatch, 3); + (void)tos_task_create(&task_warrior_0, "warrior_0", entry_task_warrior_0, NULL, + 4, stack_task_warrior_0, STK_SIZE_TASK_WIZARD, 0); + (void)tos_task_create(&task_warrior_1, "warrior_1", entry_task_warrior_1, NULL, + 4, stack_task_warrior_1, STK_SIZE_TASK_WIZARD, 0); + (void)tos_task_create(&task_warrior_2, "warrior_2", entry_task_warrior_2, NULL, + 4, stack_task_warrior_2, STK_SIZE_TASK_WIZARD, 0); + printf("wizard: now warriors are on their way, I will wait here until they all done the job\n"); + tos_countdownlatch_pend(&countdownlatch); + printf("wizard: the warriors all have done their jobs, let's make the weapon\n"); +} + +int main(void) +{ + board_init(); + tos_knl_init(); + (void)tos_task_create(&task_wizard, "wizard", entry_task_wizard, NULL, + 3, stack_task_wizard, STK_SIZE_TASK_WIZARD, 0); + tos_knl_start(); +} +``` + +##### 运行效果 + +> wizard: I will set 3 warriors to find the fragments +> wizard: now warriors are on their way, I will wait here until they all done the job +> warrior 0: I have done my job +> warrior 1: I have done my job +> warrior 2: I have done my job +> wizard: the warriors all have done their jobs, let's make the weapon + +[实例代码](./code/2.3.5 countdownlatch/main.c) + +#### 2.3.6 消息队列 + +##### 概述 + +消息队列提供了任务间传递指针数据的机制,所谓的“消息“就是指针。消息本身如何解析使用,由传递消息的两个任务自行规定,消息队列不对消息本身做任何规定和限制,消息队列仅承担指针数据的传递义务。 + +##### API讲解 + +##### 编程实例 + +1、在tos_config.h中,配置消息队列组件开关TOS_CFG_MESSAGE_QUEUE_EN: + +`#define TOS_CFG_MESSAGE_QUEUE_EN 1u` + +2、编写main.c示例代码: ```c +/* + 这里演示如何使用消息队列在sender和receiver任务之间传递消息(一个指针,此案例中这个指针信息指向的是一个字符串) + */ + #include "tos.h" #include "mcu_init.h" @@ -799,15 +963,19 @@ int main(void) #define PRIO_TASK_RECEIVER_HIGHER_PRIO 4 #define PRIO_TASK_RECEIVER_LOWER_PRIO (PRIO_TASK_RECEIVER_HIGHER_PRIO + 1) +#define MESSAGE_MAX 10 + k_stack_t stack_task_receiver_higher_prio[STK_SIZE_TASK_RECEIVER]; k_stack_t stack_task_receiver_lower_prio[STK_SIZE_TASK_RECEIVER]; k_stack_t stack_task_sender[STK_SIZE_TASK_SENDER]; +uint8_t msg_pool[MESSAGE_MAX * sizeof(void *)]; + k_task_t task_receiver_higher_prio; k_task_t task_receiver_lower_prio; k_task_t task_sender; -k_queue_t queue; +k_msg_q_t msg_q; extern void entry_task_receiver_higher_prio(void *arg); extern void entry_task_receiver_lower_prio(void *arg); @@ -817,14 +985,11 @@ void entry_task_receiver_higher_prio(void *arg) { k_err_t err; void *msg_received; - size_t msg_size; while (K_TRUE) { - err = tos_queue_pend(&queue, &msg_received, &msg_size, TOS_TIME_FOREVER); + err = tos_msg_q_pend(&msg_q, &msg_received, TOS_TIME_FOREVER); if (err == K_ERR_NONE) { - printf("entry_task_receiver_higher_prio:\n"); - printf("message body: %s\n", (char *)msg_received); - printf("message size: %d\n", msg_size); + printf("higher: msg incoming[%s]\n", (char *)msg_received); } } } @@ -833,14 +998,11 @@ void entry_task_receiver_lower_prio(void *arg) { k_err_t err; void *msg_received; - size_t msg_size; while (K_TRUE) { - err = tos_queue_pend(&queue, &msg_received, &msg_size, TOS_TIME_FOREVER); + err = tos_msg_q_pend(&msg_q, &msg_received, TOS_TIME_FOREVER); if (err == K_ERR_NONE) { - printf("entry_task_receiver_lower_prio:\n"); - printf("message body: %s\n", (char *)msg_received); - printf("message size: %d\n", msg_size); + printf("lower: msg incoming[%s]\n", (char *)msg_received); } } } @@ -848,34 +1010,25 @@ void entry_task_receiver_lower_prio(void *arg) void entry_task_sender(void *arg) { int i = 1; - char *msg_to_one_receiver = "message for one receiver[with highest priority]"; + char *msg_to_one_receiver = "message for one receiver(with highest priority)"; char *msg_to_all_receiver = "message for all receivers"; - // 此任务不断通过队列queue发送消息 while (K_TRUE) { if (i == 2) { - printf("entry_task_sender:\n"); - printf("send a message to one receiver, and shoud be the highest priority one\n"); - // 发送消息并唤醒一个等待任务,唤醒的应该是等待任务中优先级最高的 - tos_queue_post(&queue, msg_to_one_receiver, strlen(msg_to_one_receiver)); + printf("sender: send a message to one receiver, and shoud be the highest priority one\n"); + tos_msg_q_post(&msg_q, msg_to_one_receiver); } if (i == 3) { - printf("entry_task_sender:\n"); - printf("send a message to all recevier\n"); - // 发送消息并唤醒所有正在等待的任务 - tos_queue_post_all(&queue, msg_to_all_receiver, strlen(msg_to_all_receiver)); + printf("sender: send a message to all recevier\n"); + tos_msg_q_post_all(&msg_q, msg_to_all_receiver); } if (i == 4) { - printf("entry_task_sender:\n"); - printf("send a message to one receiver, and shoud be the highest priority one\n"); - // 发送消息并唤醒一个等待任务,唤醒的应该是等待任务中优先级最高的 - tos_queue_post(&queue, msg_to_one_receiver, strlen(msg_to_one_receiver)); + printf("sender: send a message to one receiver, and shoud be the highest priority one\n"); + tos_msg_q_post(&msg_q, msg_to_one_receiver); } if (i == 5) { - printf("entry_task_sender:\n"); - printf("send a message to all recevier\n"); - // 发送消息并唤醒所有正在等待的任务 - tos_queue_post_all(&queue, msg_to_all_receiver, strlen(msg_to_all_receiver)); + printf("sender: send a message to all recevier\n"); + tos_msg_q_post_all(&msg_q, msg_to_all_receiver); } tos_task_delay(1000); ++i; @@ -886,12 +1039,10 @@ int main(void) { board_init(); tos_knl_init(); - tos_queue_create(&queue); - // task_receiver_higher_prio任务的优先级较高 + tos_msg_q_create(&msg_q, msg_pool, MESSAGE_MAX); (void)tos_task_create(&task_receiver_higher_prio, "receiver_higher_prio", entry_task_receiver_higher_prio, NULL, PRIO_TASK_RECEIVER_HIGHER_PRIO, stack_task_receiver_higher_prio, STK_SIZE_TASK_RECEIVER, 0); - // task_receiver_lower_prio任务的优先级较低 (void)tos_task_create(&task_receiver_lower_prio, "receiver_lower_prio", entry_task_receiver_lower_prio, NULL, PRIO_TASK_RECEIVER_LOWER_PRIO, stack_task_receiver_lower_prio, STK_SIZE_TASK_RECEIVER, 0); @@ -903,34 +1054,363 @@ int main(void) ##### 运行效果 -> entry_task_trigger: -> send a message to one receiver, and shoud be the highest priority one -> entry_task_receiver_higher_prio: -> message body: message for one receiver[with highest priority] -> message size: 47 -> entry_task_trigger: -> send a message to all recevier -> entry_task_receiver_higher_prio: -> message body: message for all receivers -> message size: 25 -> entry_task_receiver_lower_prio: -> message body: message for all receivers -> message size: 25 -> entry_task_trigger: -> send a message to one receiver, and shoud be the highest priority one -> entry_task_receiver_higher_prio: -> message body: message for one receiver[with highest priority] -> message size: 47 -> entry_task_trigger: -> send a message to all recevier -> entry_task_receiver_higher_prio: -> message body: message for all receivers -> message size: 25 -> entry_task_receiver_lower_prio: -> message body: message for all receivers -> message size: 25 +> sender: send a message to one receiver, and shoud be the highest priority one +> higher: msg incoming[message for one receiver(with highest priority)] +> sender: send a message to all recevier +> higher: msg incoming[message for all receivers] +> lower: msg incoming[message for all receivers] +> sender: send a message to one receiver, and shoud be the highest priority one +> higher: msg incoming[message for one receiver(with highest priority)] +> sender: send a message to all recevier +> higher: msg incoming[message for all receivers] +> lower: msg incoming[message for all receivers] -[实例代码](./code/2.3.4 queue/main.c) +[实例代码](./code/2.3.6 message queue/main.c) + +#### 2.3.7 邮箱队列 + +##### 概述 + +消息队列传递的是指针,邮箱队列传递的是大片的内存数据。 + +##### API讲解 + +##### 编程实例 + +1、在tos_config.h中,配置邮箱队列组件开关TOS_CFG_MAIL_QUEUE_EN: + +`#define TOS_CFG_MAIL_QUEUE_EN 1u` + +2、编写main.c示例代码: + +```c +/* + 这里演示如何使用邮箱队列在sender和receiver任务之间传递邮箱(此案例中邮件,也就是邮箱要传递的内存数据为一个mail_t类型的结构体,从此案例中可以看出来,邮箱队列相对消息队列来说,可以传递更为复杂的内存块数据) + */ +#include "tos.h" +#include "mcu_init.h" + +#define STK_SIZE_TASK_RECEIVER 512 +#define STK_SIZE_TASK_SENDER 512 + +#define PRIO_TASK_RECEIVER_HIGHER_PRIO 4 +#define PRIO_TASK_RECEIVER_LOWER_PRIO (PRIO_TASK_RECEIVER_HIGHER_PRIO + 1) + +#define MAIL_MAX 10 + +k_stack_t stack_task_receiver_higher_prio[STK_SIZE_TASK_RECEIVER]; +k_stack_t stack_task_receiver_lower_prio[STK_SIZE_TASK_RECEIVER]; +k_stack_t stack_task_sender[STK_SIZE_TASK_SENDER]; + +typedef struct mail_st { + char *message; + int payload; +} mail_t; + +uint8_t mail_pool[MAIL_MAX * sizeof(mail_t)]; + +k_task_t task_receiver_higher_prio; +k_task_t task_receiver_lower_prio; +k_task_t task_sender; + +k_mail_q_t mail_q; + +extern void entry_task_receiver_higher_prio(void *arg); +extern void entry_task_receiver_lower_prio(void *arg); +extern void entry_task_sender(void *arg); + +void entry_task_receiver_higher_prio(void *arg) +{ + k_err_t err; + mail_t mail; + size_t mail_size; + + while (K_TRUE) { + err = tos_mail_q_pend(&mail_q, &mail, &mail_size, TOS_TIME_FOREVER); + if (err == K_ERR_NONE) { + TOS_ASSERT(mail_size == sizeof(mail_t)); + printf("higher: msg incoming[%s], payload[%d]\n", mail.message, mail.payload); + } + } +} + +void entry_task_receiver_lower_prio(void *arg) +{ + k_err_t err; + mail_t mail; + size_t mail_size; + + while (K_TRUE) { + err = tos_mail_q_pend(&mail_q, &mail, &mail_size, TOS_TIME_FOREVER); + if (err == K_ERR_NONE) { + TOS_ASSERT(mail_size == sizeof(mail_t)); + printf("lower: msg incoming[%s], payload[%d]\n", mail.message, mail.payload); + } + } +} + +void entry_task_sender(void *arg) +{ + int i = 1; + mail_t mail; + + while (K_TRUE) { + if (i == 2) { + printf("sender: send a mail to one receiver, and shoud be the highest priority one\n"); + mail.message = "1st time post"; + mail.payload = 1; + tos_mail_q_post(&mail_q, &mail, sizeof(mail_t)); + } + if (i == 3) { + printf("sender: send a message to all recevier\n"); + mail.message = "2nd time post"; + mail.payload = 2; + tos_mail_q_post_all(&mail_q, &mail, sizeof(mail_t)); + } + if (i == 4) { + printf("sender: send a message to one receiver, and shoud be the highest priority one\n"); + mail.message = "3rd time post"; + mail.payload = 3; + tos_mail_q_post(&mail_q, &mail, sizeof(mail_t)); + } + if (i == 5) { + printf("sender: send a message to all recevier\n"); + mail.message = "4th time post"; + mail.payload = 4; + tos_mail_q_post_all(&mail_q, &mail, sizeof(mail_t)); + } + tos_task_delay(1000); + ++i; + } +} + +int main(void) +{ + board_init(); + tos_knl_init(); + tos_mail_q_create(&mail_q, mail_pool, MAIL_MAX, sizeof(mail_t)); + (void)tos_task_create(&task_receiver_higher_prio, "receiver_higher_prio", + entry_task_receiver_higher_prio, NULL, PRIO_TASK_RECEIVER_HIGHER_PRIO, + stack_task_receiver_higher_prio, STK_SIZE_TASK_RECEIVER, 0); + (void)tos_task_create(&task_receiver_lower_prio, "receiver_lower_prio", + entry_task_receiver_lower_prio, NULL, PRIO_TASK_RECEIVER_LOWER_PRIO, + stack_task_receiver_lower_prio, STK_SIZE_TASK_RECEIVER, 0); + (void)tos_task_create(&task_sender, "sender", entry_task_sender, NULL, + 5, stack_task_sender, STK_SIZE_TASK_SENDER, 0); + tos_knl_start(); +} +``` + +##### 运行效果 + +> sender: send a mail to one receiver, and shoud be the highest priority one +> higher: msg incoming[1st time post], payload[1] +> sender: send a message to all recevier +> higher: msg incoming[2nd time post], payload[2] +> lower: msg incoming[2nd time post], payload[2] +> sender: send a message to one receiver, and shoud be the highest priority one +> higher: msg incoming[3rd time post], payload[3] +> sender: send a message to all recevier +> higher: msg incoming[4th time post], payload[4] +> lower: msg incoming[4th time post], payload[4] + +[实例代码](./code/2.3.7 mail queue/main.c) + +#### 2.3.8 优先级消息队列 + +##### 概述 + +优先级消息队列相对消息队列来说,给消息附加了一个优先级的概念,较高优先级的消息会比较低优先级的消息更快地被其他任务收到(本质上,消息队列的底层数据容器是环形队列,优先级消息队列的底层数据容器是优先级队列)。 + +##### API讲解 + +##### 编程实例 + +1、在tos_config.h中,配置优先级消息队列组件开关TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN: + +`#define TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN 1u` + +2、编写main.c示例代码: + +```c +#include "tos.h" +#include "mcu_init.h" + +#define STK_SIZE_TASK_RECEIVER 512 +#define STK_SIZE_TASK_SENDER 512 + +#define MESSAGE_MAX 10 + +k_stack_t stack_task_receiver[STK_SIZE_TASK_RECEIVER]; +k_stack_t stack_task_sender[STK_SIZE_TASK_SENDER]; + +uint8_t msg_pool[MESSAGE_MAX * sizeof(void *)]; + +k_task_t task_receiver; +k_task_t task_sender; + +k_prio_msg_q_t prio_msg_q; + +extern void entry_task_receiver(void *arg); +extern void entry_task_sender(void *arg); + +void entry_task_receiver(void *arg) +{ + k_err_t err; + void *msg_received; + + while (K_TRUE) { + err = tos_prio_msg_q_pend(&prio_msg_q, &msg_received, TOS_TIME_FOREVER); + if (err == K_ERR_NONE) { + printf("receiver: msg incoming[%s]\n", (char *)msg_received); + } + } +} + +void entry_task_sender(void *arg) +{ + char *msg_prio_0 = "msg with priority 0"; + char *msg_prio_1 = "msg with priority 1"; + char *msg_prio_2 = "msg with priority 2"; + + printf("sender: post a message with priority 2\n"); + tos_prio_msg_q_post(&prio_msg_q, msg_prio_2, 2); + + printf("sender: post a message with priority 1\n"); + tos_prio_msg_q_post(&prio_msg_q, msg_prio_1, 1); + + printf("sender: post a message with priority 0\n"); + tos_prio_msg_q_post(&prio_msg_q, msg_prio_0, 0); +} + +int main(void) +{ + board_init(); + tos_knl_init(); + tos_prio_msg_q_create(&prio_msg_q, msg_pool, MESSAGE_MAX); + (void)tos_task_create(&task_receiver, "receiver", entry_task_receiver, NULL, + 5, stack_task_receiver, STK_SIZE_TASK_RECEIVER, 0); + (void)tos_task_create(&task_sender, "sender", entry_task_sender, NULL, + 4, stack_task_sender, STK_SIZE_TASK_SENDER, 0); + tos_knl_start(); +} +``` + +##### 运行效果 + +> sender: post a message with priority 2 +> sender: post a message with priority 1 +> sender: post a message with priority 0 +> receiver: msg incoming[msg with priority 0] +> receiver: msg incoming[msg with priority 1] +> receiver: msg incoming[msg with priority 2] + +[实例代码](./code/2.3.8 priority message queue/main.c) + +#### 2.3.9 优先级邮箱队列 + +##### 概述 + +优先级邮箱队列相对邮箱队列来说,给邮件附加了一个优先级的概念,较高优先级的邮件会比较低优先级的邮件更快地被其他任务收到(本质上,邮箱队列的底层数据容器是环形队列,优先级邮箱队列的底层数据容器是优先级队列)。 + +##### API讲解 + +##### 编程实例 + +1、在tos_config.h中,配置优先级邮箱队列组件开关TOS_CFG_PRIORITY_MAIL_QUEUE_EN: + +`#define TOS_CFG_PRIORITY_MAIL_QUEUE_EN 1u` + +2、编写main.c示例代码: + +```c +/* + 这里演示了优先级邮箱队列的使用,从sender任务中的逻辑可以看出来,依次post了三个mail,优先级按时间顺序依次为2、1、0(数值越高优先级越低)。如果是传统的邮箱队列,那个receiver应该是依次收到优先级为2、1、0的邮件;但这是优先级邮箱队列,因而receiver会按优先级顺序收到这三个邮件,也就是依次收到优先级为0、1、2的邮件。 + */ +#include "tos.h" +#include "mcu_init.h" + +#define STK_SIZE_TASK_RECEIVER 512 +#define STK_SIZE_TASK_SENDER 512 + +#define MAIL_MAX 10 + +k_stack_t stack_task_receiver[STK_SIZE_TASK_RECEIVER]; +k_stack_t stack_task_sender[STK_SIZE_TASK_SENDER]; + +typedef struct mail_st { + char *message; + int payload; +} mail_t; + +uint8_t mail_pool[MAIL_MAX * sizeof(mail_t)]; + +k_task_t task_receiver; +k_task_t task_sender; + +k_prio_mail_q_t prio_mail_q; + +extern void entry_task_receiver(void *arg); +extern void entry_task_sender(void *arg); + +void entry_task_receiver(void *arg) +{ + k_err_t err; + mail_t mail; + size_t mail_size; + + while (K_TRUE) { + err = tos_prio_mail_q_pend(&prio_mail_q, &mail, &mail_size, TOS_TIME_FOREVER); + if (err == K_ERR_NONE) { + TOS_ASSERT(mail_size == sizeof(mail_t)); + printf("receiver: msg incoming[%s], payload[%d]\n", mail.message, mail.payload); + } + } +} + +void entry_task_sender(void *arg) +{ + mail_t mail_0, mail_1, mail_2; + + printf("sender: post a mail with priority 2\n"); + mail_2.message = "priority 2"; + mail_2.payload = 2; + tos_prio_mail_q_post(&prio_mail_q, &mail_2, sizeof(mail_t), 2); + + printf("sender: post a mail with priority 1\n"); + mail_1.message = "priority 1"; + mail_1.payload = 1; + tos_prio_mail_q_post_all(&prio_mail_q, &mail_1, sizeof(mail_t), 1); + + printf("sender: post a mail with priority 0\n"); + mail_0.message = "priority 0"; + mail_0.payload = 0; + tos_prio_mail_q_post(&prio_mail_q, &mail_0, sizeof(mail_t), 0); +} + +int main(void) +{ + board_init(); + tos_knl_init(); + tos_prio_mail_q_create(&prio_mail_q, mail_pool, MAIL_MAX, sizeof(mail_t)); + (void)tos_task_create(&task_receiver, "receiver", entry_task_receiver, NULL, + 6, stack_task_receiver, STK_SIZE_TASK_RECEIVER, 0); + (void)tos_task_create(&task_sender, "sender", entry_task_sender, NULL, + 5, stack_task_sender, STK_SIZE_TASK_SENDER, 0); + tos_knl_start(); +} +``` + +##### 运行效果 + +> sender: post a mail with priority 2 +> sender: post a mail with priority 1 +> sender: post a mail with priority 0 +> receiver: msg incoming[priority 0], payload[0] +> receiver: msg incoming[priority 1], payload[1] +> receiver: msg incoming[priority 2], payload[2] + +[实例代码](./code/2.3.9 priority mail queue/main.c) ### 2.4 内存管理 @@ -1533,188 +2013,118 @@ int main(void) ### 2.8 内核基础组件 -#### 2.8.1 消息队列 +#### 2.8.1 环形队列 ##### 概述 -消息队列提供了一种同步的传递/收取消息的机制,与队列(tos_queue)不同的是,tos_queue基于消息队列封装了一层异步的机制,实际上tos_queue的底层消息管理采用的就是消息队列。 +环形队列本质上就是支持先入先出操作的环形buffer,是系统的一个基础组件,通常用来作为实现上层机制的底层数据容器。 ##### API讲解 ##### 编程实例 -1、在tos_config.h中,配置消息队列组件开关TOS_CFG_MSG_EN: - -`#define TOS_CFG_MSG_EN 1u` - -2、在tos_config.h中,配置消息队列池大小TOS_CFG_MSG_POOL_SIZE: - -`#define TOS_CFG_MSG_POOL_SIZE 3u` - -这是消息队列池中可以承载的最大消息数量 - -3、编写main.c示例代码: +1、编写main.c示例代码: ```c #include "tos.h" #include "mcu_init.h" -#define STK_SIZE_TASK_DEMO 512 +#define STK_SIZE_TASK_DEMO 512 #define PRIO_TASK_DEMO 4 - -k_stack_t stack_task_demo[STK_SIZE_TASK_DEMO]; -k_task_t task_demo; +k_stack_t stack_task_demo[STK_SIZE_TASK_DEMO]; -k_msg_queue_t msg_queue; +k_task_t task_demo; -struct msg_st { - char *msg; - size_t size; -} msgs[TOS_CFG_MSG_POOL_SIZE] = { - { "msg 0", 6 }, - { "msg 1", 6 }, - { "msg 2", 6 }, -}; +typedef struct item_st { + int a; + int b; + int c; +} item_t; -struct msg_st dummy_msg = { "dummy msg", 10 }; +#define RING_QUEUE_ITEM_MAX 5 +uint8_t ring_q_buffer[RING_QUEUE_ITEM_MAX * sizeof(item_t)]; -extern void entry_task_demo(void *arg); +k_ring_q_t rinq_q; -void fifo_opt(void) { +void entry_task_demo(void *arg) +{ k_err_t err; int i = 0; - char *msg_received = K_NULL; - size_t msg_size = 0; - - for (; i < TOS_CFG_MSG_POOL_SIZE; ++i) { - printf("msg put: %s\n", msgs[i].msg); - err = tos_msg_queue_put(&msg_queue, (void *)msgs[i].msg, msgs[i].size, TOS_OPT_MSG_PUT_FIFO); + item_t item; + size_t item_size; + + tos_ring_q_create(&rinq_q, ring_q_buffer, RING_QUEUE_ITEM_MAX, sizeof(item_t)); + for (i = 0; i < RING_QUEUE_ITEM_MAX; ++i) { + printf("enqueue: %d %d %d\n", i, i, i); + item.a = i; + item.b = i; + item.c = i; + err = tos_ring_q_enqueue(&rinq_q, &item, sizeof(item_t)); if (err != K_ERR_NONE) { printf("should never happen\n"); } } - err = tos_msg_queue_put(&msg_queue, (void *)dummy_msg.msg, dummy_msg.size, TOS_OPT_MSG_PUT_FIFO); - if (err == K_ERR_MSG_QUEUE_FULL) { - printf("msg queue is full\n"); + err = tos_ring_q_enqueue(&rinq_q, &item, sizeof(item_t)); + if (err == K_ERR_RING_Q_FULL) { + printf("ring queue is full: %s\n", tos_ring_q_is_full(&rinq_q) ? "TRUE" : "FALSE"); } else { printf("should never happen\n"); } - - for (i = 0; i < TOS_CFG_MSG_POOL_SIZE; ++i) { - err = tos_msg_queue_get(&msg_queue, (void **)&msg_received, &msg_size); - if (err == K_ERR_NONE) { - printf("msg received: %s\n", msg_received); - printf("msg size: %d\n", msg_size); - } else { - printf("should never happen\n"); - } - } - err = tos_msg_queue_get(&msg_queue, (void **)&msg_received, &msg_size); - if (err == K_ERR_MSG_QUEUE_EMPTY) { - printf("msg queue is empty\n"); - } else { - printf("should never happen\n"); - } -} -void lifo_opt(void) { - k_err_t err; - int i = 0; - char *msg_received = K_NULL; - size_t msg_size = 0; - - for (; i < TOS_CFG_MSG_POOL_SIZE; ++i) { - printf("msg put: %s\n", msgs[i].msg); - err = tos_msg_queue_put(&msg_queue, (void *)msgs[i].msg, msgs[i].size, TOS_OPT_MSG_PUT_LIFO); - if (err != K_ERR_NONE) { - printf("should never happen\n"); - } - } - err = tos_msg_queue_put(&msg_queue, (void *)dummy_msg.msg, dummy_msg.size, TOS_OPT_MSG_PUT_LIFO); - if (err == K_ERR_MSG_QUEUE_FULL) { - printf("msg queue is full\n"); - } else { - printf("should never happen\n"); - } - - for (i = 0; i < TOS_CFG_MSG_POOL_SIZE; ++i) { - err = tos_msg_queue_get(&msg_queue, (void **)&msg_received, &msg_size); + for (i = 0; i < RING_QUEUE_ITEM_MAX; ++i) { + err = tos_ring_q_dequeue(&rinq_q, &item, &item_size); if (err == K_ERR_NONE) { - printf("msg received: %s\n", msg_received); - printf("msg size: %d\n", msg_size); + printf("dequeue: %d %d %d\n", item.a, item.b, item.c); } else { printf("should never happen\n"); } } - err = tos_msg_queue_get(&msg_queue, (void **)&msg_received, &msg_size); - if (err == K_ERR_MSG_QUEUE_EMPTY) { - printf("msg queue is empty\n"); + + err = tos_ring_q_dequeue(&rinq_q, &item, &item_size); + if (err == K_ERR_RING_Q_EMPTY) { + printf("ring queue is empty: %s\n", tos_ring_q_is_empty(&rinq_q) ? "TRUE" : "FALSE"); } else { printf("should never happen\n"); } -} -void entry_task_demo(void *arg) -{ - tos_msg_queue_create(&msg_queue); - - printf("max msg in pool: %d\n", TOS_CFG_MSG_POOL_SIZE); - printf("msg queue using TOS_OPT_MSG_PUT_FIFO\n"); - fifo_opt(); - - printf("msg queue using TOS_OPT_MSG_PUT_LIFO\n"); - lifo_opt(); } int main(void) { board_init(); - tos_knl_init(); - (void)tos_task_create(&task_demo, "demo1", entry_task_demo, NULL, + tos_knl_init(); + (void)tos_task_create(&task_demo, "demo", entry_task_demo, NULL, PRIO_TASK_DEMO, stack_task_demo, STK_SIZE_TASK_DEMO, - 0); + 0); tos_knl_start(); } ``` ##### 运行效果 -> max msg in pool: 3 -> msg queue using TOS_OPT_MSG_PUT_FIFO -> msg put: msg 0 -> msg put: msg 1 -> msg put: msg 2 -> msg queue is full -> msg received: msg 0 -> msg size: 6 -> msg received: msg 1 -> msg size: 6 -> msg received: msg 2 -> msg size: 6 -> msg queue is empty -> msg queue using TOS_OPT_MSG_PUT_LIFO -> msg put: msg 0 -> msg put: msg 1 -> msg put: msg 2 -> msg queue is full -> msg received: msg 2 -> msg size: 6 -> msg received: msg 1 -> msg size: 6 -> msg received: msg 0 -> msg size: 6 -> msg queue is empty - -[实例代码](./code/2.8.1 msg_queue/main.c) +> enqueue: 0 0 0 +> enqueue: 1 1 1 +> enqueue: 2 2 2 +> enqueue: 3 3 3 +> enqueue: 4 4 4 +> ring queue is full: TRUE +> dequeue: 0 0 0 +> dequeue: 1 1 1 +> dequeue: 2 2 2 +> dequeue: 3 3 3 +> dequeue: 4 4 4 +> ring queue is empty: TRUE + +[实例代码](./code/2.8.1 ring queue/main.c) #### 2.8.2 字符流先入先出队列 ##### 概述 -字符流先入先出队列,提供的是一个面向字符操作的环形队列实现,提供了基本的字符流入队出队操作。 +字符流先入先出队列,提供的是一个面向字符操作的环形队列实现,提供了基本的字符流入队出队操作。本质上就是环形队列中元素为字符(单字节长度)时的特例,实际上字符流先出先出队列底层的实现就是环形队列。 ##### API讲解 @@ -1726,18 +2136,18 @@ int main(void) #include "tos.h" #include "mcu_init.h" -#define STK_SIZE_TASK_DEMO 512 +#define STK_SIZE_TASK_DEMO 512 #define PRIO_TASK_DEMO 4 - -k_stack_t stack_task_demo[STK_SIZE_TASK_DEMO]; + +k_stack_t stack_task_demo[STK_SIZE_TASK_DEMO]; k_task_t task_demo; #define FIFO_BUFFER_SIZE 5 uint8_t fifo_buffer[FIFO_BUFFER_SIZE]; -k_fifo_t fifo; +k_chr_fifo_t fifo; extern void entry_task_demo(void *arg); @@ -1750,23 +2160,23 @@ void char_push(void) // 往fifo中压入FIFO_BUFFER_SIZE个字符,分别是a、b、c、d、e for (i = 0; i < FIFO_BUFFER_SIZE; ++i) { printf("char pushed: %c\n", 'a' + i); - err = tos_fifo_push(&fifo, 'a' + i); + err = tos_chr_fifo_push(&fifo, 'a' + i); if (err != K_ERR_NONE) { printf("should never happen\n"); } } // fifo最多包含FIFO_BUFFER_SIZE个字符,上文逻辑中已经压入了最大的字符量,此时继续压入字符会返回K_ERR_FIFO_FULL(fifo已满) - err = tos_fifo_push(&fifo, 'z'); - if (err == K_ERR_FIFO_FULL) { - printf("fifo is full: %s\n", tos_fifo_is_full(&fifo) ? "TRUE" : "FALSE"); + err = tos_chr_fifo_push(&fifo, 'z'); + if (err == K_ERR_RING_Q_FULL) { + printf("fifo is full: %s\n", tos_chr_fifo_is_full(&fifo) ? "TRUE" : "FALSE"); } else { printf("should never happen\n"); } // 从fifo中把所有的字符都弹出来 for (i = 0; i < FIFO_BUFFER_SIZE; ++i) { - err = tos_fifo_pop(&fifo, &data); + err = tos_chr_fifo_pop(&fifo, &data); if (err == K_ERR_NONE) { printf("%d pop: %c\n", i, data); } else { @@ -1774,9 +2184,9 @@ void char_push(void) } } // 此时继续弹出字符,会返回K_ERR_FIFO_EMPTY(fifo已空) - err = tos_fifo_pop(&fifo, &data); - if (err == K_ERR_FIFO_EMPTY) { - printf("fifo is empty: %s\n", tos_fifo_is_empty(&fifo) ? "TRUE" : "FALSE"); + err = tos_chr_fifo_pop(&fifo, &data); + if (err == K_ERR_RING_Q_EMPTY) { + printf("fifo is empty: %s\n", tos_chr_fifo_is_empty(&fifo) ? "TRUE" : "FALSE"); } else { printf("should never happen\n"); } @@ -1790,21 +2200,21 @@ void stream_push(void) uint8_t stream_pop[FIFO_BUFFER_SIZE]; // 压入字符流,字符流的长度是5,不超过fifo的最大长度FIFO_BUFFER_SIZE,会压入成功,并返回压入字符流的长度5 - count = tos_fifo_push_stream(&fifo, &stream[0], FIFO_BUFFER_SIZE); + count = tos_chr_fifo_push_stream(&fifo, &stream[0], FIFO_BUFFER_SIZE); if (count != FIFO_BUFFER_SIZE) { printf("should never happen\n"); } // 继续压入字符流(即使是长度为1的字符流),因fifo已满无法继续压入,返回长度0(压入失败) - count = tos_fifo_push_stream(&fifo, &stream_dummy[0], 1); + count = tos_chr_fifo_push_stream(&fifo, &stream_dummy[0], 1); if (count == 0) { - printf("fifo is full: %s\n", tos_fifo_is_full(&fifo) ? "TRUE" : "FALSE"); + printf("fifo is full: %s\n", tos_chr_fifo_is_full(&fifo) ? "TRUE" : "FALSE"); } else { printf("should never happen\n"); } // 将前文中压入的字符流全部弹出,返回前文压入的字符流长度5(弹出的字符流长度) - count = tos_fifo_pop_stream(&fifo, &stream_pop[0], FIFO_BUFFER_SIZE); + count = tos_chr_fifo_pop_stream(&fifo, &stream_pop[0], FIFO_BUFFER_SIZE); if (count == FIFO_BUFFER_SIZE) { printf("stream popped:\n"); for (i = 0; i < FIFO_BUFFER_SIZE; ++i) { @@ -1816,9 +2226,9 @@ void stream_push(void) } // 继续弹出,因fifo已空,返回0 - count = tos_fifo_pop_stream(&fifo, &stream_pop[0], 1); + count = tos_chr_fifo_pop_stream(&fifo, &stream_pop[0], 1); if (count == 0) { - printf("fifo is empty: %s\n", tos_fifo_is_empty(&fifo) ? "TRUE" : "FALSE"); + printf("fifo is empty: %s\n", tos_chr_fifo_is_empty(&fifo) ? "TRUE" : "FALSE"); } else { printf("should never happen\n"); } @@ -1827,7 +2237,7 @@ void stream_push(void) void entry_task_demo(void *arg) { // 创建了一个最多包含FIFO_BUFFER_SIZE个字符的fifo - tos_fifo_create(&fifo, &fifo_buffer[0], FIFO_BUFFER_SIZE); + tos_chr_fifo_create(&fifo, &fifo_buffer[0], FIFO_BUFFER_SIZE); printf("fifo, dealing with char\n"); char_push(); @@ -1839,10 +2249,10 @@ void entry_task_demo(void *arg) int main(void) { board_init(); - tos_knl_init(); - (void)tos_task_create(&task_demo, "demo1", entry_task_demo, NULL, + tos_knl_init(); + (void)tos_task_create(&task_demo, "demo", entry_task_demo, NULL, PRIO_TASK_DEMO, stack_task_demo, STK_SIZE_TASK_DEMO, - 0); + 0); tos_knl_start(); } ``` @@ -1868,7 +2278,127 @@ int main(void) > abcde > fifo is empty: TRUE -[实例代码](./code/2.8.2 fifo/main.c) +[实例代码](./code/2.8.2 char fifo/main.c) + +#### 2.8.3 二项堆 + +##### 概述 + +此组件用来内部实现优先级队列,不推荐用户使用。 + +#### 2.8.4 优先级队列 + +##### 概述 + +提供了基于优先级的队列管理。环形队列的入队出队规则是先入队的先出队(first in, first out),优先级队列的出队顺序是按照优先级来的,优先级较高的元素先出队。 + +##### API讲解 + +##### 编程实例 + +1、编写main.c示例代码: + +```c +/* + 此案例展示了优先级队列的出队规则:依次入队优先级为5、4、3、2、1的元素,出队时的顺序是按照优先级来的,也就是按优先级从高到低(数值越大,优先级越小),依次出队优先级为1、2、3、4、5元素。 + */ + +#include "tos.h" +#include "mcu_init.h" + +#define STK_SIZE_TASK_DEMO 512 + +#define PRIO_TASK_DEMO 4 + +k_stack_t stack_task_demo[STK_SIZE_TASK_DEMO]; + +k_task_t task_demo; + +typedef struct item_st { + int a; + int b; + int c; +} item_t; + +#define PRIO_QUEUE_ITEM_MAX 5 +uint8_t ring_q_buffer[PRIO_QUEUE_ITEM_MAX * sizeof(item_t)]; +uint8_t mgr_pool[TOS_PRIO_Q_MGR_ARRAY_SIZE(PRIO_QUEUE_ITEM_MAX)]; + +k_prio_q_t prio_q; + +void entry_task_demo(void *arg) +{ + k_err_t err; + int i = 0; + item_t item; + k_prio_t prio; + size_t item_size; + + tos_prio_q_create(&prio_q, mgr_pool, ring_q_buffer, PRIO_QUEUE_ITEM_MAX, sizeof(item_t)); + + for (i = PRIO_QUEUE_ITEM_MAX; i > 0; --i) { + printf("enqueue: %d %d %d\n", i, i, i); + item.a = i; + item.b = i; + item.c = i; + err = tos_prio_q_enqueue(&prio_q, &item, sizeof(item_t), i); + if (err != K_ERR_NONE) { + printf("should never happen\n"); + } + } + + err = tos_prio_q_enqueue(&prio_q, &item, sizeof(item_t), i); + if (err == K_ERR_PRIO_Q_FULL) { + printf("priority queue is full: %s\n", tos_prio_q_is_full(&prio_q) ? "TRUE" : "FALSE"); + } else { + printf("should never happen\n"); + } + + for (i = 0; i < PRIO_QUEUE_ITEM_MAX; ++i) { + err = tos_prio_q_dequeue(&prio_q, &item, &item_size, &prio); + if (err == K_ERR_NONE) { + printf("dequeue: %d %d %d, prio: %d\n", item.a, item.b, item.c, prio); + } else { + printf("should never happen\n"); + } + } + + err = tos_prio_q_dequeue(&prio_q, &item, &item_size, &prio); + if (err == K_ERR_PRIO_Q_EMPTY) { + printf("priority queue is empty: %s\n", tos_prio_q_is_empty(&prio_q) ? "TRUE" : "FALSE"); + } else { + printf("should never happen\n"); + } + +} + +int main(void) +{ + board_init(); + tos_knl_init(); + (void)tos_task_create(&task_demo, "demo", entry_task_demo, NULL, + PRIO_TASK_DEMO, stack_task_demo, STK_SIZE_TASK_DEMO, + 0); + tos_knl_start(); +} +``` + +##### 运行效果 + +> enqueue: 5 5 5 +> enqueue: 4 4 4 +> enqueue: 3 3 3 +> enqueue: 2 2 2 +> enqueue: 1 1 1 +> priority queue is full: TRUE +> dequeue: 1 1 1, prio: 1 +> dequeue: 2 2 2, prio: 2 +> dequeue: 3 3 3, prio: 3 +> dequeue: 4 4 4, prio: 4 +> dequeue: 5 5 5, prio: 5 +> priority queue is empty: TRUE + +[实例代码](./code/2.8.4 priority queue/main.c) ### 2.9 功耗管理 diff --git "a/doc/5.TencentOS-tiny-SDK\346\226\207\346\241\243.md" "b/doc/5.TencentOS tiny SDK\346\226\207\346\241\243.md" similarity index 93% rename from "doc/5.TencentOS-tiny-SDK\346\226\207\346\241\243.md" rename to "doc/5.TencentOS tiny SDK\346\226\207\346\241\243.md" index 7b875f4e..7033c05a 100644 --- "a/doc/5.TencentOS-tiny-SDK\346\226\207\346\241\243.md" +++ "b/doc/5.TencentOS tiny SDK\346\226\207\346\241\243.md" @@ -1164,6 +1164,332 @@ k_err_t tos_event_post_keep(k_event_t *event, k_event_flag_t flag); K_ERR_OBJ_INVALID event指向的并不是一个合法的事件。 +## 完成量completion + +### tos_completion_create + +```c +k_err_t tos_completion_create(k_completion_t *completion); +``` + +- **功能描述** + + 创建一个完成量。 + +- **参数解释** + + | IN/OUT | 参数名 | 描述 | + | ------ | ---------- | ---------- | + | [in] | completion | 完成量句柄 | + +- **返回值** + + K_ERR_NONE 完成量创建成功。 + + K_ERR_OBJ_PTR_NULL completion指针为空。 + +### tos_completion_destroy + +```c +k_err_t tos_completion_destroy(k_completion_t *completion); +``` + +- **功能描述** + + 销毁一个完成量。 + +- **参数解释** + + | IN/OUT | 参数名 | 描述 | + | ------ | ---------- | ---------- | + | [in] | completion | 完成量句柄 | + +- **返回值** + + K_ERR_NONE 完成量销毁成功。 + + K_ERR_OBJ_PTR_NULL completion指针为空。 + + K_ERR_OBJ_INVALID completion指向的不是一个合法的完成量。 + +### tos_completion_pend + +```c +k_err_t tos_completion_pend(k_completion_t *completion); +``` + +- **功能描述** + + 等待完成量完成(永久阻塞等待)。 + +- **参数解释** + + | IN/OUT | 参数名 | 描述 | + | ------ | ---------- | ---------- | + | [in] | completion | 完成量句柄 | + +- **返回值** + + K_ERR_NONE 完成量已完成。 + + K_ERR_PEND_SCHED_LOCKED 完成量没有完成,并且系统调度锁处于锁定状态。 + + K_ERR_PEND_DESTROY 尝试等待的完成量被删除了。 + +### tos_completion_pend_timed + +```c +k_err_t tos_completion_pend_timed(k_completion_t *completion, k_tick_t timeout); +``` + +- **功能描述** + + 尝试等待完成量完成(有限时间内的阻塞等待)。 + +- **参数解释** + + | IN/OUT | 参数名 | 描述 | + | ------ | ---------- | ------------ | + | [in] | completion | 完成量句柄 | + | [in] | timeout | 等待超时参数 | + +- **返回值** + + K_ERR_NONE 完成量已完成。 + + K_ERR_PEND_NOWAIT 此完成量尚未完成,同时timeout参数为TOS_TIME_NOWAIT(表示完成量未完成时立即返回) + + K_ERR_PEND_SCHED_LOCKED 完成量没有完成,并且系统调度锁处于锁定状态。 + + K_ERR_PEND_DESTROY 尝试等待的完成量被删除了。 + + K_ERR_PEND_TIMEOUT 在timeout时间范围内完成量未完成。 + +### tos_completion_post + +```c +k_err_t tos_completion_post(k_completion_t *completion); +``` + +- **功能描述** + + 释放完成量(此完成量状态变为已完成),并唤醒等待队列上的一个任务。如果有多个任务在此完成量的等待队列上,唤醒优先级最高的任务。 + +- **参数解释** + + | IN/OUT | 参数名 | 描述 | + | ------ | ---------- | ---------- | + | [in] | completion | 完成量句柄 | + +- **返回值** + + K_ERR_NONE 完成量释放成功。 + +### tos_completion_post_all + +```c +k_err_t tos_completion_post_all(k_completion_t *completion); +``` + +- **功能描述** + + 释放完成量(此完成量状态变为已完成),并唤醒等待队列上的所有任务。 + +- **参数解释** + + | IN/OUT | 参数名 | 描述 | + | ------ | ---------- | ---------- | + | [in] | completion | 完成量句柄 | + +- **返回值** + + K_ERR_NONE 完成量释放成功。 + +### tos_completion_reset + +```c +k_err_t tos_completion_reset(k_completion_t *completion); +``` + +- **功能描述** + + 复位完成量(将此完成量状态更改为未完成)。 + +- **参数解释** + + | IN/OUT | 参数名 | 描述 | + | ------ | ---------- | ---------- | + | [in] | completion | 完成量句柄 | + +- **返回值** + + K_ERR_NONE 完成量复位成功。 + +### tos_completion_is_done + +```c +k_err_t tos_completion_is_done(k_completion_t *completion); +``` + +- **功能描述** + + 判断此完成量是否已完成。 + +- **参数解释** + + | IN/OUT | 参数名 | 描述 | + | ------ | ---------- | ---------- | + | [in] | completion | 完成量句柄 | + +- **返回值** + + K_TRUE 完成量已完成。 + + K_FALSE 完成量未完成。 + +## 计数锁countdown latch + +### tos_countdownlatch_create + +```c +k_err_t tos_countdownlatch_create(k_countdownlatch_t *countdownlatch, k_countdownlatch_cnt_t count); +``` + +- **功能描述** + + 创建一个计数锁。 + +- **参数解释** + + | IN/OUT | 参数名 | 描述 | + | ------ | -------------- | ---------------- | + | [in] | countdownlatch | 计数锁句柄 | + | [in] | count | 期望等待的计数值 | + +- **返回值** + + K_ERR_NONE 计数锁创建成功。 + + K_ERR_OBJ_PTR_NULL countdownlatch指针为空。 + +### tos_countdownlatch_destroy + +```c +k_err_t tos_countdownlatch_destroy(k_countdownlatch_t *countdownlatch); +``` + +- **功能描述** + + 销毁一个计数锁。 + +- **参数解释** + + | IN/OUT | 参数名 | 描述 | + | ------ | -------------- | ---------- | + | [in] | countdownlatch | 计数锁句柄 | + +- **返回值** + + K_ERR_NONE 计数锁销毁成功。 + + K_ERR_OBJ_PTR_NULL countdownlatch指针为空。 + + K_ERR_OBJ_INVALID countdownlatch指向的不是一个合法的计数锁。 + +### tos_countdownlatch_pend + +```c +k_err_t tos_countdownlatch_pend(k_countdownlatch_t *countdownlatch); +``` + +- **功能描述** + + 等待计数锁完成(永久阻塞等待)。 + +- **参数解释** + + | IN/OUT | 参数名 | 描述 | + | ------ | -------------- | ---------- | + | [in] | countdownlatch | 计数量句柄 | + +- **返回值** + + K_ERR_NONE 计数锁已完成。 + + K_ERR_PEND_SCHED_LOCKED 计数锁没有完成,并且系统调度锁处于锁定状态。 + + K_ERR_PEND_DESTROY 尝试等待的计数锁被删除了。 + +### tos_countdownlatch_pend_timed + +```c +k_err_t tos_countdownlatch_pend_timed(k_countdownlatch_t *countdownlatch, k_tick_t timeout); +``` + +- **功能描述** + + 尝试等待计数锁完成(有限时间内的阻塞等待)。 + +- **参数解释** + + | IN/OUT | 参数名 | 描述 | + | ------ | -------------- | ------------ | + | [in] | countdownlatch | 计数锁句柄 | + | [in] | timeout | 等待超时参数 | + +- **返回值** + + K_ERR_NONE 计数锁已完成。 + + K_ERR_PEND_NOWAIT 此计数锁尚未完成,同时timeout参数为TOS_TIME_NOWAIT(表示计数锁未完成时立即返回) + + K_ERR_PEND_SCHED_LOCKED 计数锁没有完成,并且系统调度锁处于锁定状态。 + + K_ERR_PEND_DESTROY 尝试等待的计数锁被删除了。 + + K_ERR_PEND_TIMEOUT 在timeout时间范围内计数锁未完成。 + +### tos_countdownlatch_post + +```c +k_err_t tos_countdownlatch_post(k_countdownlatch_t *countdownlatch); +``` + +- **功能描述** + + 计数锁(此计数锁的计数值减一),并唤醒等待队列上的一个任务。如果有多个任务在此计数锁的等待队列上,唤醒优先级最高的任务。 + +- **参数解释** + + | IN/OUT | 参数名 | 描述 | + | ------ | -------------- | ---------- | + | [in] | countdownlatch | 计数锁句柄 | + +- **返回值** + + K_ERR_NONE 计数锁释放成功。 + +### tos_countdownlatch_reset + +```c +k_err_t tos_countdownlatch_reset(k_countdownlatch_t *countdownlatch, k_countdownlatch_cnt_t count); +``` + +- **功能描述** + + 复位计数锁(将此计数锁的计数值复位为新的期望值)。 + +- **参数解释** + + | IN/OUT | 参数名 | 描述 | + | ------ | -------------- | -------------------- | + | [in] | countdownlatch | 计数锁句柄 | + | [in] | count | 期望复位的新的计数值 | + +- **返回值** + + K_ERR_NONE 计数锁复位成功。 + ## 消息队列message queue ### tos_msg_q_create diff --git "a/doc/6.TencentOS tiny\345\270\270\350\247\201\351\227\256\351\242\230.md" "b/doc/6.TencentOS tiny \345\270\270\350\247\201\351\227\256\351\242\230.md" similarity index 100% rename from "doc/6.TencentOS tiny\345\270\270\350\247\201\351\227\256\351\242\230.md" rename to "doc/6.TencentOS tiny \345\270\270\350\247\201\351\227\256\351\242\230.md" diff --git "a/doc/7.TencentOS tiny\350\257\215\346\261\207\350\241\250.md" "b/doc/7.TencentOS tiny \350\257\215\346\261\207\350\241\250.md" similarity index 100% rename from "doc/7.TencentOS tiny\350\257\215\346\261\207\350\241\250.md" rename to "doc/7.TencentOS tiny \350\257\215\346\261\207\350\241\250.md" diff --git "a/doc/8.TencentOS-tiny\345\257\271\346\216\245\350\205\276\350\256\257\344\272\221IoTHub\345\274\200\345\217\221\346\214\207\345\215\227.md" "b/doc/8.TencentOS tiny \345\257\271\346\216\245\350\205\276\350\256\257\344\272\221IoTHub\345\274\200\345\217\221\346\214\207\345\215\227.md" similarity index 100% rename from "doc/8.TencentOS-tiny\345\257\271\346\216\245\350\205\276\350\256\257\344\272\221IoTHub\345\274\200\345\217\221\346\214\207\345\215\227.md" rename to "doc/8.TencentOS tiny \345\257\271\346\216\245\350\205\276\350\256\257\344\272\221IoTHub\345\274\200\345\217\221\346\214\207\345\215\227.md" diff --git a/doc/TencentOS-tiny-porting-guide-gcc.md b/doc/TencentOS tiny porting guide gcc.md similarity index 100% rename from doc/TencentOS-tiny-porting-guide-gcc.md rename to doc/TencentOS tiny porting guide gcc.md diff --git a/doc/TencentOS-tiny-porting-guide-iar.md b/doc/TencentOS tiny porting guide iar.md similarity index 100% rename from doc/TencentOS-tiny-porting-guide-iar.md rename to doc/TencentOS tiny porting guide iar.md diff --git a/doc/TencentOS-tiny-porting-guide-keil.md b/doc/TencentOS tiny porting guide keil.md similarity index 100% rename from doc/TencentOS-tiny-porting-guide-keil.md rename to doc/TencentOS tiny porting guide keil.md diff --git a/doc/TencentOS-tiny-porting(MacOS_STM32CubeIDE).md b/doc/TencentOS tiny porting(MacOS_STM32CubeIDE).md similarity index 100% rename from doc/TencentOS-tiny-porting(MacOS_STM32CubeIDE).md rename to doc/TencentOS tiny porting(MacOS_STM32CubeIDE).md diff --git "a/doc/TencentOS-tiny-\344\273\243\347\240\201\347\233\256\345\275\225\350\257\264\346\230\216.md" "b/doc/TencentOS tiny \344\273\243\347\240\201\347\233\256\345\275\225\350\257\264\346\230\216.md" similarity index 100% rename from "doc/TencentOS-tiny-\344\273\243\347\240\201\347\233\256\345\275\225\350\257\264\346\230\216.md" rename to "doc/TencentOS tiny \344\273\243\347\240\201\347\233\256\345\275\225\350\257\264\346\230\216.md" diff --git "a/doc/TencentOS-tiny\345\256\232\345\210\266\345\274\200\345\217\221\346\235\277\345\205\245\351\227\250\346\214\207\345\215\227.pdf" "b/doc/TencentOS tiny \345\256\232\345\210\266\345\274\200\345\217\221\346\235\277\345\205\245\351\227\250\346\214\207\345\215\227.pdf" similarity index 100% rename from "doc/TencentOS-tiny\345\256\232\345\210\266\345\274\200\345\217\221\346\235\277\345\205\245\351\227\250\346\214\207\345\215\227.pdf" rename to "doc/TencentOS tiny \345\256\232\345\210\266\345\274\200\345\217\221\346\235\277\345\205\245\351\227\250\346\214\207\345\215\227.pdf" diff --git a/doc/code/2.3.4 completion/main.c b/doc/code/2.3.4 completion/main.c new file mode 100644 index 00000000..054d51c8 --- /dev/null +++ b/doc/code/2.3.4 completion/main.c @@ -0,0 +1,39 @@ +#include "tos.h" +#include "mcu_init.h" + +#define STK_SIZE_TASK_WAIT 512 +#define STK_SIZE_TASK_TRIGGER 512 + +k_stack_t stack_task_wait[STK_SIZE_TASK_WAIT]; +k_stack_t stack_task_trigger[STK_SIZE_TASK_TRIGGER]; + +k_task_t task_wait; +k_task_t task_trigger; + +k_completion_t completion; + +void entry_task_wait(void *arg) +{ + printf("wait: I won't go further until someone do the trigger(make it 'complete')\n"); + tos_completion_pend(&completion); + printf("wait: someone has made it complete, so I'm here\n"); +} + +void entry_task_trigger(void *arg) +{ + printf("trigger: I'm the one who make complete, anyone waitting for the complete won't go further until I do the trigger\n"); + tos_completion_post(&completion); + printf("trigger: I have done the completion\n"); +} + +int main(void) +{ + board_init(); + tos_knl_init(); + tos_completion_create(&completion); + (void)tos_task_create(&task_wait, "wait", entry_task_wait, NULL, + 3, stack_task_wait, STK_SIZE_TASK_WAIT, 0); + (void)tos_task_create(&task_trigger, "trigger", entry_task_trigger, NULL, + 4, stack_task_trigger, STK_SIZE_TASK_TRIGGER, 0); + tos_knl_start(); +} diff --git a/doc/code/2.3.5 countdownlatch/main.c b/doc/code/2.3.5 countdownlatch/main.c new file mode 100644 index 00000000..1f493a42 --- /dev/null +++ b/doc/code/2.3.5 countdownlatch/main.c @@ -0,0 +1,61 @@ +#include "tos.h" +#include "mcu_init.h" + +#define STK_SIZE_TASK_WIZARD 512 +#define STK_SIZE_TASK_WARRIOR 512 + +k_stack_t stack_task_wizard[STK_SIZE_TASK_WIZARD]; +k_stack_t stack_task_warrior_0[STK_SIZE_TASK_WARRIOR]; +k_stack_t stack_task_warrior_1[STK_SIZE_TASK_WARRIOR]; +k_stack_t stack_task_warrior_2[STK_SIZE_TASK_WARRIOR]; + +k_task_t task_wizard; +k_task_t task_warrior_0; +k_task_t task_warrior_1; +k_task_t task_warrior_2; + +k_countdownlatch_t countdownlatch; + +void entry_task_warrior_0(void *arg) +{ + printf("warrior 0: I have done my job\n"); + tos_countdownlatch_post(&countdownlatch); +} + +void entry_task_warrior_1(void *arg) +{ + printf("warrior 1: I have done my job\n"); + tos_countdownlatch_post(&countdownlatch); +} + +void entry_task_warrior_2(void *arg) +{ + printf("warrior 2: I have done my job\n"); + tos_countdownlatch_post(&countdownlatch); +} + + +void entry_task_wizard(void *arg) +{ + printf("wizard: I will set 3 warriors to find the fragments\n"); + tos_countdownlatch_create(&countdownlatch, 3); + (void)tos_task_create(&task_warrior_0, "warrior_0", entry_task_warrior_0, NULL, + 4, stack_task_warrior_0, STK_SIZE_TASK_WIZARD, 0); + (void)tos_task_create(&task_warrior_1, "warrior_1", entry_task_warrior_1, NULL, + 4, stack_task_warrior_1, STK_SIZE_TASK_WIZARD, 0); + (void)tos_task_create(&task_warrior_2, "warrior_2", entry_task_warrior_2, NULL, + 4, stack_task_warrior_2, STK_SIZE_TASK_WIZARD, 0); + printf("wizard: now warriors are on their way, I will wait here until they all done the job\n"); + tos_countdownlatch_pend(&countdownlatch); + printf("wizard: the warriors all have done their jobs, let's make the weapon\n"); +} + +int main(void) +{ + board_init(); + tos_knl_init(); + (void)tos_task_create(&task_wizard, "wizard", entry_task_wizard, NULL, + 3, stack_task_wizard, STK_SIZE_TASK_WIZARD, 0); + tos_knl_start(); +} + diff --git a/doc/code/2.3.4 queue/main.c b/doc/code/2.3.6 message queue/main.c similarity index 57% rename from doc/code/2.3.4 queue/main.c rename to doc/code/2.3.6 message queue/main.c index d166a4dd..788a7c38 100644 --- a/doc/code/2.3.4 queue/main.c +++ b/doc/code/2.3.6 message queue/main.c @@ -7,15 +7,19 @@ #define PRIO_TASK_RECEIVER_HIGHER_PRIO 4 #define PRIO_TASK_RECEIVER_LOWER_PRIO (PRIO_TASK_RECEIVER_HIGHER_PRIO + 1) +#define MESSAGE_MAX 10 + k_stack_t stack_task_receiver_higher_prio[STK_SIZE_TASK_RECEIVER]; k_stack_t stack_task_receiver_lower_prio[STK_SIZE_TASK_RECEIVER]; k_stack_t stack_task_sender[STK_SIZE_TASK_SENDER]; +uint8_t msg_pool[MESSAGE_MAX * sizeof(void *)]; + k_task_t task_receiver_higher_prio; k_task_t task_receiver_lower_prio; k_task_t task_sender; -k_queue_t queue; +k_msg_q_t msg_q; extern void entry_task_receiver_higher_prio(void *arg); extern void entry_task_receiver_lower_prio(void *arg); @@ -25,14 +29,11 @@ void entry_task_receiver_higher_prio(void *arg) { k_err_t err; void *msg_received; - size_t msg_size; while (K_TRUE) { - err = tos_queue_pend(&queue, &msg_received, &msg_size, TOS_TIME_FOREVER); + err = tos_msg_q_pend(&msg_q, &msg_received, TOS_TIME_FOREVER); if (err == K_ERR_NONE) { - printf("entry_task_receiver_higher_prio:\n"); - printf("message body: %s\n", (char *)msg_received); - printf("message size: %d\n", msg_size); + printf("higher: msg incoming[%s]\n", (char *)msg_received); } } } @@ -41,14 +42,11 @@ void entry_task_receiver_lower_prio(void *arg) { k_err_t err; void *msg_received; - size_t msg_size; while (K_TRUE) { - err = tos_queue_pend(&queue, &msg_received, &msg_size, TOS_TIME_FOREVER); + err = tos_msg_q_pend(&msg_q, &msg_received, TOS_TIME_FOREVER); if (err == K_ERR_NONE) { - printf("entry_task_receiver_lower_prio:\n"); - printf("message body: %s\n", (char *)msg_received); - printf("message size: %d\n", msg_size); + printf("lower: msg incoming[%s]\n", (char *)msg_received); } } } @@ -56,29 +54,25 @@ void entry_task_receiver_lower_prio(void *arg) void entry_task_sender(void *arg) { int i = 1; - char *msg_to_one_receiver = "message for one receiver[with highest priority]"; + char *msg_to_one_receiver = "message for one receiver(with highest priority)"; char *msg_to_all_receiver = "message for all receivers"; while (K_TRUE) { if (i == 2) { - printf("entry_task_sender:\n"); - printf("send a message to one receiver, and shoud be the highest priority one\n"); - tos_queue_post(&queue, msg_to_one_receiver, strlen(msg_to_one_receiver)); + printf("sender: send a message to one receiver, and shoud be the highest priority one\n"); + tos_msg_q_post(&msg_q, msg_to_one_receiver); } if (i == 3) { - printf("entry_task_sender:\n"); - printf("send a message to all recevier\n"); - tos_queue_post_all(&queue, msg_to_all_receiver, strlen(msg_to_all_receiver)); + printf("sender: send a message to all recevier\n"); + tos_msg_q_post_all(&msg_q, msg_to_all_receiver); } if (i == 4) { - printf("entry_task_sender:\n"); - printf("send a message to one receiver, and shoud be the highest priority one\n"); - tos_queue_post(&queue, msg_to_one_receiver, strlen(msg_to_one_receiver)); + printf("sender: send a message to one receiver, and shoud be the highest priority one\n"); + tos_msg_q_post(&msg_q, msg_to_one_receiver); } if (i == 5) { - printf("entry_task_sender:\n"); - printf("send a message to all recevier\n"); - tos_queue_post_all(&queue, msg_to_all_receiver, strlen(msg_to_all_receiver)); + printf("sender: send a message to all recevier\n"); + tos_msg_q_post_all(&msg_q, msg_to_all_receiver); } tos_task_delay(1000); ++i; @@ -89,7 +83,7 @@ int main(void) { board_init(); tos_knl_init(); - tos_queue_create(&queue); + tos_msg_q_create(&msg_q, msg_pool, MESSAGE_MAX); (void)tos_task_create(&task_receiver_higher_prio, "receiver_higher_prio", entry_task_receiver_higher_prio, NULL, PRIO_TASK_RECEIVER_HIGHER_PRIO, stack_task_receiver_higher_prio, STK_SIZE_TASK_RECEIVER, 0); @@ -100,4 +94,3 @@ int main(void) 4, stack_task_sender, STK_SIZE_TASK_SENDER, 0); tos_knl_start(); } - diff --git a/doc/code/2.3.7 mail queue/main.c b/doc/code/2.3.7 mail queue/main.c new file mode 100644 index 00000000..99b2fbb5 --- /dev/null +++ b/doc/code/2.3.7 mail queue/main.c @@ -0,0 +1,113 @@ +#include "tos.h" +#include "mcu_init.h" + +#define STK_SIZE_TASK_RECEIVER 512 +#define STK_SIZE_TASK_SENDER 512 + +#define PRIO_TASK_RECEIVER_HIGHER_PRIO 4 +#define PRIO_TASK_RECEIVER_LOWER_PRIO (PRIO_TASK_RECEIVER_HIGHER_PRIO + 1) + +#define MAIL_MAX 10 + +k_stack_t stack_task_receiver_higher_prio[STK_SIZE_TASK_RECEIVER]; +k_stack_t stack_task_receiver_lower_prio[STK_SIZE_TASK_RECEIVER]; +k_stack_t stack_task_sender[STK_SIZE_TASK_SENDER]; + +typedef struct mail_st { + char *message; + int payload; +} mail_t; + +uint8_t mail_pool[MAIL_MAX * sizeof(mail_t)]; + +k_task_t task_receiver_higher_prio; +k_task_t task_receiver_lower_prio; +k_task_t task_sender; + +k_mail_q_t mail_q; + +extern void entry_task_receiver_higher_prio(void *arg); +extern void entry_task_receiver_lower_prio(void *arg); +extern void entry_task_sender(void *arg); + +void entry_task_receiver_higher_prio(void *arg) +{ + k_err_t err; + mail_t mail; + size_t mail_size; + + while (K_TRUE) { + err = tos_mail_q_pend(&mail_q, &mail, &mail_size, TOS_TIME_FOREVER); + if (err == K_ERR_NONE) { + TOS_ASSERT(mail_size == sizeof(mail_t)); + printf("higher: msg incoming[%s], payload[%d]\n", mail.message, mail.payload); + } + } +} + +void entry_task_receiver_lower_prio(void *arg) +{ + k_err_t err; + mail_t mail; + size_t mail_size; + + while (K_TRUE) { + err = tos_mail_q_pend(&mail_q, &mail, &mail_size, TOS_TIME_FOREVER); + if (err == K_ERR_NONE) { + TOS_ASSERT(mail_size == sizeof(mail_t)); + printf("lower: msg incoming[%s], payload[%d]\n", mail.message, mail.payload); + } + } +} + +void entry_task_sender(void *arg) +{ + int i = 1; + mail_t mail; + + while (K_TRUE) { + if (i == 2) { + printf("sender: send a mail to one receiver, and shoud be the highest priority one\n"); + mail.message = "1st time post"; + mail.payload = 1; + tos_mail_q_post(&mail_q, &mail, sizeof(mail_t)); + } + if (i == 3) { + printf("sender: send a message to all recevier\n"); + mail.message = "2nd time post"; + mail.payload = 2; + tos_mail_q_post_all(&mail_q, &mail, sizeof(mail_t)); + } + if (i == 4) { + printf("sender: send a message to one receiver, and shoud be the highest priority one\n"); + mail.message = "3rd time post"; + mail.payload = 3; + tos_mail_q_post(&mail_q, &mail, sizeof(mail_t)); + } + if (i == 5) { + printf("sender: send a message to all recevier\n"); + mail.message = "4th time post"; + mail.payload = 4; + tos_mail_q_post_all(&mail_q, &mail, sizeof(mail_t)); + } + tos_task_delay(1000); + ++i; + } +} + +int main(void) +{ + board_init(); + tos_knl_init(); + tos_mail_q_create(&mail_q, mail_pool, MAIL_MAX, sizeof(mail_t)); + (void)tos_task_create(&task_receiver_higher_prio, "receiver_higher_prio", + entry_task_receiver_higher_prio, NULL, PRIO_TASK_RECEIVER_HIGHER_PRIO, + stack_task_receiver_higher_prio, STK_SIZE_TASK_RECEIVER, 0); + (void)tos_task_create(&task_receiver_lower_prio, "receiver_lower_prio", + entry_task_receiver_lower_prio, NULL, PRIO_TASK_RECEIVER_LOWER_PRIO, + stack_task_receiver_lower_prio, STK_SIZE_TASK_RECEIVER, 0); + (void)tos_task_create(&task_sender, "sender", entry_task_sender, NULL, + 5, stack_task_sender, STK_SIZE_TASK_SENDER, 0); + tos_knl_start(); +} + diff --git a/doc/code/2.3.8 priority message queue/main.c b/doc/code/2.3.8 priority message queue/main.c new file mode 100644 index 00000000..c3de617a --- /dev/null +++ b/doc/code/2.3.8 priority message queue/main.c @@ -0,0 +1,62 @@ +#include "tos.h" +#include "mcu_init.h" + +#define STK_SIZE_TASK_RECEIVER 512 +#define STK_SIZE_TASK_SENDER 512 + +#define MESSAGE_MAX 10 + +k_stack_t stack_task_receiver[STK_SIZE_TASK_RECEIVER]; +k_stack_t stack_task_sender[STK_SIZE_TASK_SENDER]; + +uint8_t msg_pool[MESSAGE_MAX * sizeof(void *)]; + +k_task_t task_receiver; +k_task_t task_sender; + +k_prio_msg_q_t prio_msg_q; + +extern void entry_task_receiver(void *arg); +extern void entry_task_sender(void *arg); + +void entry_task_receiver(void *arg) +{ + k_err_t err; + void *msg_received; + + while (K_TRUE) { + err = tos_prio_msg_q_pend(&prio_msg_q, &msg_received, TOS_TIME_FOREVER); + if (err == K_ERR_NONE) { + printf("receiver: msg incoming[%s]\n", (char *)msg_received); + } + } +} + +void entry_task_sender(void *arg) +{ + char *msg_prio_0 = "msg with priority 0"; + char *msg_prio_1 = "msg with priority 1"; + char *msg_prio_2 = "msg with priority 2"; + + printf("sender: post a message with priority 2\n"); + tos_prio_msg_q_post(&prio_msg_q, msg_prio_2, 2); + + printf("sender: post a message with priority 1\n"); + tos_prio_msg_q_post(&prio_msg_q, msg_prio_1, 1); + + printf("sender: post a message with priority 0\n"); + tos_prio_msg_q_post(&prio_msg_q, msg_prio_0, 0); +} + +int main(void) +{ + board_init(); + tos_knl_init(); + tos_prio_msg_q_create(&prio_msg_q, msg_pool, MESSAGE_MAX); + (void)tos_task_create(&task_receiver, "receiver", entry_task_receiver, NULL, + 5, stack_task_receiver, STK_SIZE_TASK_RECEIVER, 0); + (void)tos_task_create(&task_sender, "sender", entry_task_sender, NULL, + 4, stack_task_sender, STK_SIZE_TASK_SENDER, 0); + tos_knl_start(); +} + diff --git a/doc/code/2.3.9 priority mail queue/main.c b/doc/code/2.3.9 priority mail queue/main.c new file mode 100644 index 00000000..e7ce4d53 --- /dev/null +++ b/doc/code/2.3.9 priority mail queue/main.c @@ -0,0 +1,73 @@ +#include "tos.h" +#include "mcu_init.h" + +#define STK_SIZE_TASK_RECEIVER 512 +#define STK_SIZE_TASK_SENDER 512 + +#define MAIL_MAX 10 + +k_stack_t stack_task_receiver[STK_SIZE_TASK_RECEIVER]; +k_stack_t stack_task_sender[STK_SIZE_TASK_SENDER]; + +typedef struct mail_st { + char *message; + int payload; +} mail_t; + +uint8_t mail_pool[MAIL_MAX * sizeof(mail_t)]; + +k_task_t task_receiver; +k_task_t task_sender; + +k_prio_mail_q_t prio_mail_q; + +extern void entry_task_receiver(void *arg); +extern void entry_task_sender(void *arg); + +void entry_task_receiver(void *arg) +{ + k_err_t err; + mail_t mail; + size_t mail_size; + + while (K_TRUE) { + err = tos_prio_mail_q_pend(&prio_mail_q, &mail, &mail_size, TOS_TIME_FOREVER); + if (err == K_ERR_NONE) { + TOS_ASSERT(mail_size == sizeof(mail_t)); + printf("receiver: msg incoming[%s], payload[%d]\n", mail.message, mail.payload); + } + } +} + +void entry_task_sender(void *arg) +{ + mail_t mail_0, mail_1, mail_2; + + printf("sender: post a mail with priority 2\n"); + mail_2.message = "priority 2"; + mail_2.payload = 2; + tos_prio_mail_q_post(&prio_mail_q, &mail_2, sizeof(mail_t), 2); + + printf("sender: post a mail with priority 1\n"); + mail_1.message = "priority 1"; + mail_1.payload = 1; + tos_prio_mail_q_post_all(&prio_mail_q, &mail_1, sizeof(mail_t), 1); + + printf("sender: post a mail with priority 0\n"); + mail_0.message = "priority 0"; + mail_0.payload = 0; + tos_prio_mail_q_post(&prio_mail_q, &mail_0, sizeof(mail_t), 0); +} + +int main(void) +{ + board_init(); + tos_knl_init(); + tos_prio_mail_q_create(&prio_mail_q, mail_pool, MAIL_MAX, sizeof(mail_t)); + (void)tos_task_create(&task_receiver, "receiver", entry_task_receiver, NULL, + 6, stack_task_receiver, STK_SIZE_TASK_RECEIVER, 0); + (void)tos_task_create(&task_sender, "sender", entry_task_sender, NULL, + 5, stack_task_sender, STK_SIZE_TASK_SENDER, 0); + tos_knl_start(); +} + diff --git a/doc/code/2.8.1 msg_queue/main.c b/doc/code/2.8.1 msg_queue/main.c deleted file mode 100644 index 9f78e14b..00000000 --- a/doc/code/2.8.1 msg_queue/main.c +++ /dev/null @@ -1,123 +0,0 @@ -#include "tos.h" -#include "mcu_init.h" - -#define STK_SIZE_TASK_DEMO 512 - -#define PRIO_TASK_DEMO 4 - -k_stack_t stack_task_demo[STK_SIZE_TASK_DEMO]; - -k_task_t task_demo; - -k_msg_queue_t msg_queue; - -struct msg_st { - char *msg; - size_t size; -} msgs[TOS_CFG_MSG_POOL_SIZE] = { - { "msg 0", 6 }, - { "msg 1", 6 }, - { "msg 2", 6 }, -}; - -struct msg_st dummy_msg = { "dummy msg", 10 }; - -extern void entry_task_demo(void *arg); - -void fifo_opt(void) { - k_err_t err; - int i = 0; - char *msg_received = K_NULL; - size_t msg_size = 0; - - for (; i < TOS_CFG_MSG_POOL_SIZE; ++i) { - printf("msg put: %s\n", msgs[i].msg); - err = tos_msg_queue_put(&msg_queue, (void *)msgs[i].msg, msgs[i].size, TOS_OPT_MSG_PUT_FIFO); - if (err != K_ERR_NONE) { - printf("should never happen\n"); - } - } - - err = tos_msg_queue_put(&msg_queue, (void *)dummy_msg.msg, dummy_msg.size, TOS_OPT_MSG_PUT_FIFO); - if (err == K_ERR_MSG_QUEUE_FULL) { - printf("msg queue is full\n"); - } else { - printf("should never happen\n"); - } - - for (i = 0; i < TOS_CFG_MSG_POOL_SIZE; ++i) { - err = tos_msg_queue_get(&msg_queue, (void **)&msg_received, &msg_size); - if (err == K_ERR_NONE) { - printf("msg received: %s\n", msg_received); - printf("msg size: %d\n", msg_size); - } else { - printf("should never happen\n"); - } - } - err = tos_msg_queue_get(&msg_queue, (void **)&msg_received, &msg_size); - if (err == K_ERR_MSG_QUEUE_EMPTY) { - printf("msg queue is empty\n"); - } else { - printf("should never happen\n"); - } -} - -void lifo_opt(void) { - k_err_t err; - int i = 0; - char *msg_received = K_NULL; - size_t msg_size = 0; - - for (; i < TOS_CFG_MSG_POOL_SIZE; ++i) { - printf("msg put: %s\n", msgs[i].msg); - err = tos_msg_queue_put(&msg_queue, (void *)msgs[i].msg, msgs[i].size, TOS_OPT_MSG_PUT_LIFO); - if (err != K_ERR_NONE) { - printf("should never happen\n"); - } - } - err = tos_msg_queue_put(&msg_queue, (void *)dummy_msg.msg, dummy_msg.size, TOS_OPT_MSG_PUT_LIFO); - if (err == K_ERR_MSG_QUEUE_FULL) { - printf("msg queue is full\n"); - } else { - printf("should never happen\n"); - } - - for (i = 0; i < TOS_CFG_MSG_POOL_SIZE; ++i) { - err = tos_msg_queue_get(&msg_queue, (void **)&msg_received, &msg_size); - if (err == K_ERR_NONE) { - printf("msg received: %s\n", msg_received); - printf("msg size: %d\n", msg_size); - } else { - printf("should never happen\n"); - } - } - err = tos_msg_queue_get(&msg_queue, (void **)&msg_received, &msg_size); - if (err == K_ERR_MSG_QUEUE_EMPTY) { - printf("msg queue is empty\n"); - } else { - printf("should never happen\n"); - } -} - -void entry_task_demo(void *arg) -{ - tos_msg_queue_create(&msg_queue); - - printf("max msg in pool: %d\n", TOS_CFG_MSG_POOL_SIZE); - printf("msg queue using TOS_OPT_MSG_PUT_FIFO\n"); - fifo_opt(); - - printf("msg queue using TOS_OPT_MSG_PUT_LIFO\n"); - lifo_opt(); -} - -int main(void) -{ - board_init(); - tos_knl_init(); - (void)tos_task_create(&task_demo, "demo1", entry_task_demo, NULL, - PRIO_TASK_DEMO, stack_task_demo, STK_SIZE_TASK_DEMO, - 0); - tos_knl_start(); -} - diff --git a/doc/code/2.8.1 ring queue/main.c b/doc/code/2.8.1 ring queue/main.c new file mode 100644 index 00000000..94c8b934 --- /dev/null +++ b/doc/code/2.8.1 ring queue/main.c @@ -0,0 +1,76 @@ +#include "tos.h" +#include "mcu_init.h" + +#define STK_SIZE_TASK_DEMO 512 + +#define PRIO_TASK_DEMO 4 + +k_stack_t stack_task_demo[STK_SIZE_TASK_DEMO]; + +k_task_t task_demo; + +typedef struct item_st { + int a; + int b; + int c; +} item_t; + +#define RING_QUEUE_ITEM_MAX 5 +uint8_t ring_q_buffer[RING_QUEUE_ITEM_MAX * sizeof(item_t)]; + +k_ring_q_t rinq_q; + +void entry_task_demo(void *arg) +{ + k_err_t err; + int i = 0; + item_t item; + size_t item_size; + + tos_ring_q_create(&rinq_q, ring_q_buffer, RING_QUEUE_ITEM_MAX, sizeof(item_t)); + for (i = 0; i < RING_QUEUE_ITEM_MAX; ++i) { + printf("enqueue: %d %d %d\n", i, i, i); + item.a = i; + item.b = i; + item.c = i; + err = tos_ring_q_enqueue(&rinq_q, &item, sizeof(item_t)); + if (err != K_ERR_NONE) { + printf("should never happen\n"); + } + } + + err = tos_ring_q_enqueue(&rinq_q, &item, sizeof(item_t)); + if (err == K_ERR_RING_Q_FULL) { + printf("ring queue is full: %s\n", tos_ring_q_is_full(&rinq_q) ? "TRUE" : "FALSE"); + } else { + printf("should never happen\n"); + } + + for (i = 0; i < RING_QUEUE_ITEM_MAX; ++i) { + err = tos_ring_q_dequeue(&rinq_q, &item, &item_size); + if (err == K_ERR_NONE) { + printf("dequeue: %d %d %d\n", item.a, item.b, item.c); + } else { + printf("should never happen\n"); + } + } + + err = tos_ring_q_dequeue(&rinq_q, &item, &item_size); + if (err == K_ERR_RING_Q_EMPTY) { + printf("ring queue is empty: %s\n", tos_ring_q_is_empty(&rinq_q) ? "TRUE" : "FALSE"); + } else { + printf("should never happen\n"); + } + +} + +int main(void) +{ + board_init(); + tos_knl_init(); + (void)tos_task_create(&task_demo, "demo", entry_task_demo, NULL, + PRIO_TASK_DEMO, stack_task_demo, STK_SIZE_TASK_DEMO, + 0); + tos_knl_start(); +} + diff --git a/doc/code/2.8.2 fifo/main.c b/doc/code/2.8.2 char fifo/main.c similarity index 95% rename from doc/code/2.8.2 fifo/main.c rename to doc/code/2.8.2 char fifo/main.c index aab8ba2f..51789e2a 100644 --- a/doc/code/2.8.2 fifo/main.c +++ b/doc/code/2.8.2 char fifo/main.c @@ -31,7 +31,7 @@ void char_push(void) } err = tos_chr_fifo_push(&fifo, 'z'); - if (err == K_ERR_FIFO_FULL) { + if (err == K_ERR_RING_Q_FULL) { printf("fifo is full: %s\n", tos_chr_fifo_is_full(&fifo) ? "TRUE" : "FALSE"); } else { printf("should never happen\n"); @@ -46,7 +46,7 @@ void char_push(void) } } err = tos_chr_fifo_pop(&fifo, &data); - if (err == K_ERR_FIFO_EMPTY) { + if (err == K_ERR_RING_Q_EMPTY) { printf("fifo is empty: %s\n", tos_chr_fifo_is_empty(&fifo) ? "TRUE" : "FALSE"); } else { printf("should never happen\n"); @@ -106,7 +106,7 @@ int main(void) { board_init(); tos_knl_init(); - (void)tos_task_create(&task_demo, "demo1", entry_task_demo, NULL, + (void)tos_task_create(&task_demo, "demo", entry_task_demo, NULL, PRIO_TASK_DEMO, stack_task_demo, STK_SIZE_TASK_DEMO, 0); tos_knl_start(); diff --git a/doc/code/2.8.4 priority queue/main.c b/doc/code/2.8.4 priority queue/main.c new file mode 100644 index 00000000..9e4a7deb --- /dev/null +++ b/doc/code/2.8.4 priority queue/main.c @@ -0,0 +1,78 @@ +#include "tos.h" +#include "mcu_init.h" + +#define STK_SIZE_TASK_DEMO 512 + +#define PRIO_TASK_DEMO 4 + +k_stack_t stack_task_demo[STK_SIZE_TASK_DEMO]; + +k_task_t task_demo; + +typedef struct item_st { + int a; + int b; + int c; +} item_t; + +#define PRIO_QUEUE_ITEM_MAX 5 +uint8_t ring_q_buffer[PRIO_QUEUE_ITEM_MAX * sizeof(item_t)]; +uint8_t mgr_pool[TOS_PRIO_Q_MGR_ARRAY_SIZE(PRIO_QUEUE_ITEM_MAX)]; + +k_prio_q_t prio_q; + +void entry_task_demo(void *arg) +{ + k_err_t err; + int i = 0; + item_t item; + k_prio_t prio; + size_t item_size; + + tos_prio_q_create(&prio_q, mgr_pool, ring_q_buffer, PRIO_QUEUE_ITEM_MAX, sizeof(item_t)); + + for (i = PRIO_QUEUE_ITEM_MAX; i > 0; --i) { + printf("enqueue: %d %d %d\n", i, i, i); + item.a = i; + item.b = i; + item.c = i; + err = tos_prio_q_enqueue(&prio_q, &item, sizeof(item_t), i); + if (err != K_ERR_NONE) { + printf("should never happen\n"); + } + } + + err = tos_prio_q_enqueue(&prio_q, &item, sizeof(item_t), i); + if (err == K_ERR_PRIO_Q_FULL) { + printf("priority queue is full: %s\n", tos_prio_q_is_full(&prio_q) ? "TRUE" : "FALSE"); + } else { + printf("should never happen\n"); + } + + for (i = 0; i < PRIO_QUEUE_ITEM_MAX; ++i) { + err = tos_prio_q_dequeue(&prio_q, &item, &item_size, &prio); + if (err == K_ERR_NONE) { + printf("dequeue: %d %d %d, prio: %d\n", item.a, item.b, item.c, prio); + } else { + printf("should never happen\n"); + } + } + + err = tos_prio_q_dequeue(&prio_q, &item, &item_size, &prio); + if (err == K_ERR_PRIO_Q_EMPTY) { + printf("priority queue is empty: %s\n", tos_prio_q_is_empty(&prio_q) ? "TRUE" : "FALSE"); + } else { + printf("should never happen\n"); + } + +} + +int main(void) +{ + board_init(); + tos_knl_init(); + (void)tos_task_create(&task_demo, "demo", entry_task_demo, NULL, + PRIO_TASK_DEMO, stack_task_demo, STK_SIZE_TASK_DEMO, + 0); + tos_knl_start(); +} diff --git a/kernel/core/include/tos_completion.h b/kernel/core/include/tos_completion.h index d8f35d10..41f07a41 100644 --- a/kernel/core/include/tos_completion.h +++ b/kernel/core/include/tos_completion.h @@ -86,9 +86,7 @@ __API__ k_err_t tos_completion_pend_timed(k_completion_t *completion, k_tick_t t * @param[in] timeout how much time(in k_tick_t) we would like to wait. * * @return errcode - * @retval #K_ERR_PEND_NOWAIT we get nothing, and we don't wanna wait. * @retval #K_ERR_PEND_SCHED_LOCKED we can wait, but scheduler is locked. - * @retval #K_ERR_PEND_TIMEOUT the time we wait is up, we get nothing. * @retval #K_ERR_PEND_DESTROY the completion we are pending is destroyed. * @retval #K_ERR_NONE return successfully. */ diff --git a/net/at/include/tos_at.h b/net/at/include/tos_at.h index 88a532e6..e08934df 100644 --- a/net/at/include/tos_at.h +++ b/net/at/include/tos_at.h @@ -144,7 +144,7 @@ typedef struct at_agent_st { * @retval -1 write failed(error). * @retval none -1 the number of bytes written. */ -int tos_at_channel_write(int channel_id, uint8_t *buffer, size_t buffer_len); +__API__ int tos_at_channel_write(int channel_id, uint8_t *buffer, size_t buffer_len); /** * @brief Read data from a channel. @@ -161,7 +161,7 @@ int tos_at_channel_write(int channel_id, uint8_t *buffer, size_t buffer_len); * @retval -1 read failed(error). * @retval none -1 the number of bytes read. */ -int tos_at_channel_read_timed(int channel_id, uint8_t *buffer, size_t buffer_len, uint32_t timeout); +__API__ int tos_at_channel_read_timed(int channel_id, uint8_t *buffer, size_t buffer_len, uint32_t timeout); /** * @brief Read data from a channel. @@ -177,7 +177,7 @@ int tos_at_channel_read_timed(int channel_id, uint8_t *buffer, size_t buffer_len * @retval -1 read failed(error). * @retval none -1 the number of bytes read. */ -int tos_at_channel_read(int channel_id, uint8_t *buffer, size_t buffer_len); +__API__ int tos_at_channel_read(int channel_id, uint8_t *buffer, size_t buffer_len); /** * @brief Allocate a channel. @@ -193,7 +193,7 @@ int tos_at_channel_read(int channel_id, uint8_t *buffer, size_t buffer_len); * @retval -1 allocate failed(error). * @retval none -1 the id of the channel. */ -int tos_at_channel_alloc_id(int channel_id, const char *ip, const char *port); +__API__ int tos_at_channel_alloc_id(int channel_id, const char *ip, const char *port); /** * @brief Allocate a channel. @@ -208,7 +208,7 @@ int tos_at_channel_alloc_id(int channel_id, const char *ip, const char *port); * @retval -1 allocate failed(error). * @retval none -1 the id of the channel. */ -int tos_at_channel_alloc(const char *ip, const char *port); +__API__ int tos_at_channel_alloc(const char *ip, const char *port); /** * @brief Free a channel. @@ -222,7 +222,7 @@ int tos_at_channel_alloc(const char *ip, const char *port); * @retval -1 free failed(error). * @retval 0 free successfully. */ -int tos_at_channel_free(int channel_id); +__API__ int tos_at_channel_free(int channel_id); /** * @brief Set channel broken. @@ -261,7 +261,7 @@ __API__ int tos_at_channel_is_working(int channel_id); * @retval -1 initialize failed(error). * @retval 0 initialize successfully. */ -int tos_at_init(hal_uart_port_t uart_port, at_event_t *event_table, size_t event_table_size); +__API__ int tos_at_init(hal_uart_port_t uart_port, at_event_t *event_table, size_t event_table_size); /** * @brief De-initialize the at framework. @@ -270,7 +270,7 @@ int tos_at_init(hal_uart_port_t uart_port, at_event_t *event_table, size_t event * * @return None */ -void tos_at_deinit(void); +__API__ void tos_at_deinit(void); /** * @brief Create a echo struct. @@ -286,7 +286,7 @@ void tos_at_deinit(void); * @retval -1 create failed(error). * @retval 0 create successfully. */ -int tos_at_echo_create(at_echo_t *echo, char *buffer, size_t buffer_size, char *echo_expect); +__API__ int tos_at_echo_create(at_echo_t *echo, char *buffer, size_t buffer_size, char *echo_expect); /** * @brief Execute an at command. @@ -301,7 +301,7 @@ int tos_at_echo_create(at_echo_t *echo, char *buffer, size_t buffer_size, char * * @retval -1 execute failed(error). * @retval 0 execute successfully. */ -int tos_at_cmd_exec(at_echo_t *echo, uint32_t timeout, const char *cmd, ...); +__API__ int tos_at_cmd_exec(at_echo_t *echo, uint32_t timeout, const char *cmd, ...); /** * @brief Execute an at command. @@ -317,7 +317,7 @@ int tos_at_cmd_exec(at_echo_t *echo, uint32_t timeout, const char *cmd, ...); * @retval -1 execute failed(error). * @retval 0 execute successfully. */ -int tos_at_cmd_exec_until(at_echo_t *echo, uint32_t timeout, const char *cmd, ...); +__API__ int tos_at_cmd_exec_until(at_echo_t *echo, uint32_t timeout, const char *cmd, ...); /** * @brief Send raw data througth uart. @@ -333,7 +333,7 @@ int tos_at_cmd_exec_until(at_echo_t *echo, uint32_t timeout, const char *cmd, .. * @retval -1 execute failed(error). * @retval 0 execute successfully. */ -int tos_at_raw_data_send(at_echo_t *echo, uint32_t timeout, const uint8_t *buf, size_t size); +__API__ int tos_at_raw_data_send(at_echo_t *echo, uint32_t timeout, const uint8_t *buf, size_t size); /** * @brief Send raw data througth uart. @@ -350,7 +350,7 @@ int tos_at_raw_data_send(at_echo_t *echo, uint32_t timeout, const uint8_t *buf, * @retval -1 execute failed(error). * @retval 0 execute successfully. */ -int tos_at_raw_data_send_until(at_echo_t *echo, uint32_t timeout, const uint8_t *buf, size_t size); +__API__ int tos_at_raw_data_send_until(at_echo_t *echo, uint32_t timeout, const uint8_t *buf, size_t size); /** * @brief Write byte to the at uart. @@ -362,7 +362,7 @@ int tos_at_raw_data_send_until(at_echo_t *echo, uint32_t timeout, const uint8_t * * @return None */ -void tos_at_uart_write_byte(uint8_t data); +__API__ void tos_at_uart_write_byte(uint8_t data); /** * @brief A global lock provided by at framework. @@ -376,7 +376,7 @@ void tos_at_uart_write_byte(uint8_t data); * @retval -1 pend failed(error). * @retval 0 pend successfully. */ -int tos_at_global_lock_pend(void); +__API__ int tos_at_global_lock_pend(void); /** * @brief A global lock provided by at framework. @@ -390,7 +390,7 @@ int tos_at_global_lock_pend(void); * @retval -1 post failed(error). * @retval 0 post successfully. */ -int tos_at_global_lock_post(void); +__API__ int tos_at_global_lock_post(void); /** * @brief Read data from the uart. @@ -403,7 +403,7 @@ int tos_at_global_lock_post(void); * * @return length of the data read from the uart. */ -int tos_at_uart_read(uint8_t *buffer, size_t buffer_len); +__API__ int tos_at_uart_read(uint8_t *buffer, size_t buffer_len); /** * @brief Read data from the uart. @@ -416,7 +416,7 @@ int tos_at_uart_read(uint8_t *buffer, size_t buffer_len); * * @return length of the data read from the uart. */ -int tos_at_uart_readline(uint8_t *buffer, size_t buffer_len); +__API__ int tos_at_uart_readline(uint8_t *buffer, size_t buffer_len); /** * @brief Read data from the uart. @@ -429,7 +429,7 @@ int tos_at_uart_readline(uint8_t *buffer, size_t buffer_len); * * @return length of the data read from the uart. */ -int tos_at_uart_drain(uint8_t *buffer, size_t buffer_len); +__API__ int tos_at_uart_drain(uint8_t *buffer, size_t buffer_len); /** * @brief Get the remote ip of a channel. @@ -441,7 +441,7 @@ int tos_at_uart_drain(uint8_t *buffer, size_t buffer_len); * * @return remote ip of the channel. */ -const char *tos_at_agent_channel_ip_get(int channel_id); +__API__ const char *tos_at_agent_channel_ip_get(int channel_id); /** * @brief Get the remote port of a channel. @@ -453,7 +453,7 @@ const char *tos_at_agent_channel_ip_get(int channel_id); * * @return remote port of the channel. */ -const char *tos_at_agent_channel_port_get(int channel_id); +__API__ const char *tos_at_agent_channel_port_get(int channel_id); #endif /* __AT_AGENT_H_ */ -- GitLab