向大家请教一下uc/os-II多任务的运行机制?有一个如下的uc/os-II源代码,就是采用信号量机制使两个任务共享
向大家请教一下uc/os-II多任务的运行机制?
有一个如下的uc/os-II源代码,就是采用信号量机制使两个任务共享一个串口com1,去打印一条字符串。
#include "config.h"
#defineTask0StkLengh64 // Define the Task0 stack length 定义用户任务0的堆栈长度
#defineTask1StkLengh64 // Define the Task1 stack length 定义用户任务1的堆栈长度
OS_STKTask0Stk [Task0StkLengh]; // Define the Task0 stack 定义用户任务0的堆栈
OS_STKTask1Stk [Task1StkLengh]; // Define the Task1 stack 定义用户任务1的堆栈
OS_EVENT *UART0_Sem;
void Task0(void *pdata); // Task0 任务0
void Task1(void *pdata); // Task1 任务1
int main (void)
{
OSInit ();
OSTaskCreate (Task0,(void *)0, &Task0Stk[Task0StkLengh - 1], 2);
OSTaskCreate (Task1,(void *)0, &Task1Stk[Task1StkLengh - 1], 3);
UART0_Sem = OSSemCreate(1);
OSStart ();
return 0;
}
/************************************************************************************
** Function name: Task0
** Descriptions: 从UART0输出字符串"Task0 is running!"
************************************************************************************/
void Task0(void *pdata)
{ uint8 err;
pdata = pdata;
TargetInit ();
while (1)
{
OSSemPend(UART0_Sem, 0, &err);
UART_SendStr("Task0 is running!\r\n");
OSTimeDly(OS_TICKS_PER_SEC);
OSSemPost(UART0_Sem);
}
}
/************************************************************************************
** Function name: Task1
** Descriptions: 从UART0输出字符串"Task1 is running!"
************************************************************************************/
void Task1(void *pdata)
{ uint8 err;
pdata = pdata;
while (1)
{
OSSemPend(UART0_Sem, 0, &err);
UART_SendStr("Task1 is running!\r\n");
OSTimeDly(OS_TICKS_PER_SEC);
OSSemPost(UART0_Sem);
}
}
这段代码我的理解如下:
按照uc/os-II的任务调度机制,当执行OSStart ();去启动多任务的时候,task0会首先运行。
task0第一次去申请信号量时成功,会占用串口1打印出Task0 is running!
此后调用系统延时函数,按照系统延时函数的功能,该函数会把task0任务移出就绪表,之后
进行一次任务级的任务切换。task1将处于运行态,所以task1将去申请信号量,由于task0在未释放
信号量之前调用了 OSTimeDly(OS_TICKS_PER_SEC);使自己挂起了。task1申请失败,将自己插入
信号量等待队列中,那么此时task0和task1处于了死锁状态了。这时候只剩下空闲任务在运行了。
------------------------------------
但是参考书上给出了运行结果将是task0和task1两个任务无规律的执行,每一次打印出
一条关于自己信息的完整字符串!
请问一下,这个代码到底是怎么样运行的?
谢谢!
另外问一个题外话,在发帖的时候怎么编辑源代码格式?
[解决办法]题外话能回答,技术的回答不上。
编辑的时候从编辑框的上方插入源代码,选择相应的语言列别就可以。
[解决办法]
Task0运行 -> 得到UART0_Sem->打印->挂起->Task1运行->不能得到UART0_Sem,挂起->idletask运行
->Task0定时时间到,运行,post信号量->Task0 得到UART0_Sem->。。。。。
你的代码有问题。task1会饿死。
OSSemPend(UART0_Sem, 0, &err);
UART_SendStr("Task0 is running!\r\n");
OSSemPost(UART0_Sem);
OSTimeDly(OS_TICKS_PER_SEC);
改成这样的顺序试试。