任务创建
在调度系统启动前,至少要先创建一个任务,否则直接退出
可以在任务中创建新的任务,不管是独立栈任务还是共享栈任务
独立栈任务中可以创建新的独立栈任务和共享栈任务
共享栈任务中同样可以创建新的独立栈任务和共享栈任务,而且在创建共享栈任务时可以使用同一个共享栈
独立栈任务和共享栈任务一共可以创建最多32个任务(需要修改宏配置)
任务销毁
没有提供该功能接口函数,任务入口函数主动退出则自动将任务销毁。
可以通过等待任务退出接口函数在其他任务中等待该任务退出。
任务阻塞
当前任务阻塞提供两种方式:
时间阻塞:需要阻塞多长时间,等时间满足后才会继续执行
事件阻塞:通过事件阻塞,只有事件触发后才会继续执行
使用说明
任务创建/退出
对于创建独立栈任务还是共享栈任务的示例代码:
复制
uint8_t g_task1Stack[1024 * 2];
uint8_t g_task2Stack[1024 * 2];
uint8_t g_task3Stack[1024 * 2];
uint8_t g_sharedStack[1024 * 2];
// 执行完成就退出的任务
void taskfunc3(int arg)
{
...
cotOs_Wait(1000);
...
cotOs_Wait(1000);
}
void taskfunc1(int arg)
{
/* 不管taskfunc1是独立栈任务还是共享栈任务,都支持创建子任务 */
cotOs_CreatTask(taskfunc3, COT_OS_UNIQUE_STACK, g_task3Stack, sizeof(g_task3Stack), 0);// 创建独立栈任务
cotOs_CreatTask(taskfunc3, COT_OS_SHARED_STACK, g_sharedStack, sizeof(g_sharedStack), 0); // 创建共享栈任务
while (1)
{
...
cotOs_Wait(1000);
}
}
void taskfunc2(int arg)
{
while (1)
{
...
cotOs_Wait(10);
}
}
int main(void)
{
cotOs_Init(GetTimerMs);
#if 0
/* 创建独立栈任务 */
cotOs_CreatTask(taskfunc1, COT_OS_UNIQUE_STACK, g_task1Stack, sizeof(g_task1Stack), 0);
cotOs_CreatTask(taskfunc2, COT_OS_UNIQUE_STACK, g_task2Stack, sizeof(g_task2Stack), 0);
#else
/* 创建共享栈任务 */
cotOs_CreatTask(taskfunc1, COT_OS_SHARED_STACK, g_sharedStack, sizeof(g_sharedStack), 0);
cotOs_CreatTask(taskfunc2, COT_OS_SHARED_STACK, g_sharedStack, sizeof(g_sharedStack), 0);
#endif
cotOs_Start();
}
任务限制
对于创建独立栈任务还是共享栈任务,共享栈任务有限制要求,禁止在任务入口函数的嵌套函数中阻塞
复制
uint8_t g_task1Stack[1024 * 2];
uint8_t g_sharedStack[1024 * 2];
void func1_1(void)
{
...
cotOs_Wait(1000);
...
cotOs_Wait(1000);
}
/* 独立栈任务 */
void taskfunc1(int arg)
{
int arr[10]; // 可以直接定义变量使用
while (1)
{
func1_1();// 可以在嵌套函数中使用阻塞等待
...
cotOs_Wait(1000);
}
}
void func2_1(void)
{
...
}
/* 共享栈任务 */
void taskfunc2(int arg)
{
static int arr[10];// 建议使用static定义任务内变量或者不定义变量
while (1)
{
func2_1();// 禁止在嵌套函数中使用阻塞等待
...
cotOs_Wait(10);
}
}
int main(void)
{
cotOs_Init(GetTimerMs);
/* 创建独立栈任务 */
cotOs_CreatTask(taskfunc1, COT_OS_UNIQUE_STACK, g_task1Stack, sizeof(g_task1Stack), 0);
/* 创建共享栈任务 */
cotOs_CreatTask(taskfunc2, COT_OS_SHARED_STACK, g_sharedStack, sizeof(g_sharedStack), 0);
cotOs_Start();
}
任务阻塞/退出
通过时间和事件的方式阻塞
复制
uint8_t g_task1Stack[1024 * 2];
uint8_t g_task2Stack[1024 * 2];
uint8_t g_task3Stack[1024 * 2];
uint8_t g_sharedStack[1024 * 2];
CotOSCondition_t g_eventCv;
// 执行完成就退出的任务
void taskfunc3(int arg)
{
...
cotOs_ConditionWait(&g_eventCv);
...
}
void taskfunc1(int arg)
{
cotOsTask_t task = cotOs_CreatTask(taskfunc3, COT_OS_UNIQUE_STACK, g_task3Stack, sizeof(g_task3Stack), 0);
while (1)
{
...
cotOs_Wait(1000);
if (...)
{
// 等待 taskfunc3 任务运行结束后才退出 taskfunc1
cotOs_Join(task);
break;
}
}
}
void taskfunc2(int arg)
{
while (1)
{
...
cotOs_Wait(10);
if (...)
{
cotOs_ConditionNotify(&g_eventCv);// 通知 taskfunc3 继续执行
}
}
}
int main(void)
{
cotOs_Init(GetTimerMs);
cotOs_CreatTask(taskfunc1, COT_OS_SHARED_STACK, g_sharedStack, sizeof(g_sharedStack), 0);
cotOs_CreatTask(taskfunc2, COT_OS_SHARED_STACK, g_sharedStack, sizeof(g_sharedStack), 0);
cotOs_Start();
}
不同栈类型任务应用场景
独立栈任务(有栈任务)
重量级任务: 提供更多的控制,适用于需要更精确地管理任务状态的情况和执行计算密集型任务的场景
更可预测的内存使用: 在创建时分配栈空间,可以更好地控制内存使用,适用于需要更可预测内存行为的场景
递归调用: 更容易处理递归调用,因为每个任务都有独立的栈空间
共享栈任务(无栈任务)
轻量级任务: 通常更轻量,适用于大量小任务的场景。
内存效率: 适用于内存受限的环境,因为不需要为每个任务分配各自的栈空间(备份栈除外)。 |