uCOS-II任务的挂起和恢复
文章转自:http://www.cnblogs.com/amanlikethis/p/4150452.html
函数描述
- OSTaskSuspend()
功能描述:无条件挂起一个任务。调用此函数的任务也可以传递参数OS_PRIO_SELF,挂起调用任务本身。
函数原型:INT8U OSTaskSuspend ( INT8U prio);
参数说明:prio为指定要获取挂起的任务优先级,也可以指定参数OS_PRIO_SELF,挂起任务本身。此时,下一个优先级最高的就绪任务将运行。
返回值:
OSTaskSuspend()的返回值为下述之一:
-
OS_NO_ERR:函数调用成功。
-
OS_TASK_ SUSPEND_IDLE:试图挂起μC/OS-II中的空闲任务(Idle task)。此为非法操作。
-
OS_PRIO_INVALID:参数指定的优先级大于OS_LOWEST_PRIO或没有设定OS_PRIO_SELF的值。
-
OS_TASK_ SUSPEND _PRIO:要挂起的任务不存在。
- OSTaskResume()
功能描述:唤醒一个用OSTaskSuspend()函数挂起的任务。OSTaskResume()也是唯一能“解挂”挂起任务的函数。
函数原型:NT8U OSTaskResume ( INT8U prio)
参数说明:prio指定要唤醒任务的优先级
返回值:
OSTaskResume ()的返回值为下述之一:
-
OS_NO_ERR:函数调用成功。
-
OS_TASK_RESUME_PRIO:要唤醒的任务不存在。
-
OS_TASK_NOT_SUSPENDED:要唤醒的任务不在挂起状态。
-
OS_PRIO_INVALID:参数指定的优先级大于或等于
OS_LOWEST_PRIO。
使用注意
当前任务挂起后,只有其他任务才能唤醒被挂起的任务。任务挂起后,系统会重新进行任务调度,运行下一个优先级最高的就绪任务。唤醒挂起任务需要调用函数OSTaskResume()。 任务的挂起是可以叠加到其他操作上的。例如,任务被挂起时正在进行延时操作,那么任务的唤醒就需要两个条件:延时的结束以及其他任务的唤醒操作。又如,任务被挂起时正在等待信号量,当任务从信号量的等待对列中清除后也不能立即运行,而必须等到被唤醒后。
一个测试范例
测试平台:STM32
测试代码:
#define StartTaskPrio 4
#define TASK1_PRIO 5
#define TASK2_PRIO 6
int main(void)
{
USART1_Config();
OSInit();
OSTaskCreate(StartTask, (void *)0, &StartTaskStk[StartTaskStkLength-1], StartTaskPrio);
OSStart();
return 0;
}
void StartTask(void *p_arg)
{
(void)p_arg;
USART1_printf("\nStartTask has been running !");
SysTick_Config(SystemCoreClock / OS_TICKS_PER_SEC);
OSTaskCreate(Task1, (void *)0, &task1_stk[TASK1_STK_SIZE-1], TASK1_PRIO);
OSTaskCreate(Task2, (void *)0, &task2_stk[TASK2_STK_SIZE-1], TASK2_PRIO);
OSTaskSuspend(StartTaskPrio);
}
void Task1(void *p_arg)
{
(void)p_arg;
while(1){
USART1_printf("\nTask1 has been running !");
OSTaskSuspend(TASK1_PRIO);
}
}
void Task2(void *p_arg)
{
(void)p_arg;
while(1){
USART1_printf("\n\nTask2 start running !");
OSTaskResume(TASK1_PRIO);
USART1_printf("\nTask2 has been running !");
OSTimeDly(2*OS_TICKS_PER_SEC);
}
}
程序执行时序流程:
运行结果:
增加
设计一个有两个任务MyTask和YourTask的应用程序,MyTask运行5次挂起自己,YourTask运行10次,为MyTask解挂;MyTask运行20次请求删除任务YourTask。要求写出完整代码
#include "includes.h" //9
#define TASK_STK_SIZE 512
OS_STK MyTaskStk[TASK_STK_SIZE];
OS_STK YourTaskStk[TASK_STK_SIZE];
INT16S key;
INT8U x = 0, y = 0;
INT8U time_x = 0, time_y = 0;
void MyTask( void *pdata );
void YourTask( void *pdata );
void main( void ) { //8
char *s_M = "M";
OSInit();
PC_DOSSaveReturn();
PC_VectSet( uCOS, OSCtxSw );
OSTaskCreate( MyTask, s_M, &MyTaskStk[TASK_STK_SIZE - 1], 1 );
OSStart();
}
void MyTask( void *pdata ) { //36
char *s_Y = "Y";
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata;
OS_ENTER_CRITICAL();
PC_VectSet( 0x08, OSTickISR );
PC_SetTickRate( OS_TICKS_PER_SEC );
OS_EXIT_CRITICAL();
OSStatInit();
OSTaskCreate( YourTask, s_Y, &YourTaskStk[TASK_STK_SIZE - 1], 2 );
for (;; ) {
if(time_x == 5) {
OSTaskSuspend(OS_PRIO_SELF);
}
if(time_x == 20) {
while(OSTaskDelReq(2)!=OS_TASK_NOT_EXIST) {
OSTimeDly(1);
}
}
if ( x >= 10 ) {
x = 0;
y += 2;
}
PC_DispChar( x, y, *(char *) pdata, DISP_BGND_BLACK + DISP_FGND_WHITE );
x += 1;
time_x += 1;
if ( PC_GetKey( &key ) == TRUE ) {
if ( key == 0x1B ) {
PC_DOSReturn();
}
}
OSTimeDlyHMSM( 0, 0, 1, 0 );
}
}
void YourTask( void *pdata ) { //24
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata;
for (;; ) {
if(OSTaskDelReq(OS_PRIO_SELF)==OS_TASK_DEL_REQ) {
OSTaskDel(OS_PRIO_SELF);
}
else {
if(time_y == 10) {
OSTaskResume( 1 );
}
if ( x >= 10 ) {
x = 0;
y += 2;
}
PC_DispChar( x, y, *(char *) pdata, DISP_BGND_BLACK + DISP_FGND_WHITE );
x += 1;
time_y += 1;
OSTimeDlyHMSM( 0, 0, 1, 0 );
}
}
}