1:ucos基本任务框架
基于linux平台的ucos 2.86应用程序示例如下:主要是根据ucos中的API创建俩个简单的task。其代码结构为:
#include <stdio.h>
#include <stdlib.h>
#include "ucos_ii.h"
/* Function common to all tasks */
void MyTask( void *p_arg )
{
char* sTaskName = (char*)p_arg;
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
while(1)
{
/* printf uses mutex to get terminal access, therefore must enter critical section */
OS_ENTER_CRITICAL();
printf( "Name: %s\n", sTaskName );
OS_EXIT_CRITICAL();
/* Delay so other tasks may execute. */
OSTimeDly(50);
}/* while */
}
int main (void)
{
/* pthreads allocates its own memory for task stacks. This UCOS linux port needs a minimum stack size
in order to pass the function information within the port. */
INT8U Stk1[ OSMinStkSize() ];
INT8U Stk2[ OSMinStkSize() ];
char sTask1[] = "Task 1";
char sTask2[] = "Task 2";
OSInit();
OSTaskCreate( MyTask, sTask1, (void*)Stk1, 4 );
OSTaskCreate( MyTask, sTask2, (void*)Stk2, 5 );
OSStart();
return 0;
}
上面的运行的结果类似如下:上面的多余的打印信息是在ucos中添加了一个调试信息而至。
2:系统任务之:空闲任务 OS_TaskIdle
说明:系统创建的三个任务的优先级为:
#define OS_TASK_TMR_PRIO (OS_LOWEST_PRIO - 2) //时间处理task优先级
#define OS_TASK_STAT_PRIO (OS_LOWEST_PRIO - 1) /* Statistic task priority */
#define OS_TASK_IDLE_PRIO (OS_LOWEST_PRIO) /* IDLE task priority */
空闲任务的初始化过程如下:
static void OS_InitTaskIdle (void)
{
#if OS_TASK_NAME_SIZE > 7
INT8U err;
#endif
#if OS_TASK_CREATE_EXT_EN > 0
#if OS_STK_GROWTH == 1
(void)OSTaskCreateExt(OS_TaskIdle,
(void *)0, /* No arguments passed to OS_TaskIdle() */
&OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], /* Set Top-Of-Stack */
OS_TASK_IDLE_PRIO, /* Lowest priority level */
OS_TASK_IDLE_ID,
&OSTaskIdleStk[0], /* Set Bottom-Of-Stack */
OS_TASK_IDLE_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */
#else
(void)OSTaskCreateExt(OS_TaskIdle,
(void *)0, /* No arguments passed to OS_TaskIdle() */
&OSTaskIdleStk[0], /* Set Top-Of-Stack */
OS_TASK_IDLE_PRIO, /* Lowest priority level */
OS_TASK_IDLE_ID,
&OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], /* Set Bottom-Of-Stack */
OS_TASK_IDLE_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */
#endif
#else
#if OS_STK_GROWTH == 1
(void)OSTaskCreate(OS_TaskIdle,
(void *)0,
&OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1],
OS_TASK_IDLE_PRIO);
#else
(void)OSTaskCreate(OS_TaskIdle,
(void *)0,
&OSTaskIdleStk[0],
OS_TASK_IDLE_PRIO);
#endif
#endif
#if OS_TASK_NAME_SIZE > 14
OSTaskNameSet(OS_TASK_IDLE_PRIO, (INT8U *)"uC/OS-II Idle", &err);
#else
#if OS_TASK_NAME_SIZE > 7
OSTaskNameSet(OS_TASK_IDLE_PRIO, (INT8U *)"OS-Idle", &err);
#endif
#endif
}
其中在上面空闲任务的创建过程中使用了俩个不同的版本的函数来创建task。对创建函数的分析后面会进行。
其中task处理函数为:其中没有做本质的处理,用户可以在其中加入自己的处理代码来实现实时性要求的功能。
void OS_TaskIdle (void *p_arg)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
(void)p_arg; /* Prevent compiler warning for not using 'p_arg' */
for (;;) {
OS_ENTER_CRITICAL();
OSIdleCtr++;
OS_EXIT_CRITICAL();
OSTaskIdleHook(); /* Call user definable HOOK */
}
}
3:系统任务之:统计任务
创建统计任务之前,有一段统计相关的初始化代码:
*********************************************************************************************************
* STATISTICS INITIALIZATION
*
* Description: This function is called by your application to establish CPU usage by first determining
* how high a 32-bit counter would count to in 1 second if no other tasks were to execute
* during that time. CPU usage is then determined by a low priority task which keeps track
* of this 32-bit counter every second but this time, with other tasks running. CPU usage is
* determined by:
*
* OSIdleCtr
* CPU Usage (%) = 100 * (1 - ------------)
* OSIdleCtrMax
*CPU的使用率的计算公式
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
#if OS_TASK_STAT_EN > 0
void OSStatInit (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
OSTimeDly(2); /* Synchronize with clock tick */
OS_ENTER_CRITICAL();
OSIdleCtr = 0L; /* Clear idle counter 对空闲任务的计算变量 清零操作 */
OS_EXIT_CRITICAL();
OSTimeDly(OS_TICKS_PER_SEC / 10); /* Determine MAX. idle counter value for 1/10 second */
OS_ENTER_CRITICAL();
OSIdleCtrMax = OSIdleCtr; /* Store maximum idle counter count in 1/10 second */
OSStatRdy = OS_TRUE;
OS_EXIT_CRITICAL();
}
#endif
/*$PAGE*/
统计任务的创建代码如下:
#if OS_TASK_STAT_EN > 0
static void OS_InitTaskStat (void)
{
#if OS_TASK_NAME_SIZE > 7
INT8U err;
#endif
#if OS_TASK_CREATE_EXT_EN > 0
#if OS_STK_GROWTH == 1
(void)OSTaskCreateExt(OS_TaskStat,
(void *)0, /* No args passed to OS_TaskStat()*/
&OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], /* Set Top-Of-Stack */
OS_TASK_STAT_PRIO, /* One higher than the idle task */
OS_TASK_STAT_ID,
&OSTaskStatStk[0], /* Set Bottom-Of-Stack */
OS_TASK_STAT_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */
#else
(void)OSTaskCreateExt(OS_TaskStat,
(void *)0, /* No args passed to OS_TaskStat()*/
&OSTaskStatStk[0], /* Set Top-Of-Stack */
OS_TASK_STAT_PRIO, /* One higher than the idle task */
OS_TASK_STAT_ID,
&OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], /* Set Bottom-Of-Stack */
OS_TASK_STAT_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */
#endif
#else
#if OS_STK_GROWTH == 1
(void)OSTaskCreate(OS_TaskStat,
(void *)0, /* No args passed to OS_TaskStat()*/
&OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], /* Set Top-Of-Stack */
OS_TASK_STAT_PRIO); /* One higher than the idle task */
#else
(void)OSTaskCreate(OS_TaskStat,
(void *)0, /* No args passed to OS_TaskStat()*/
&OSTaskStatStk[0], /* Set Top-Of-Stack */
OS_TASK_STAT_PRIO); /* One higher than the idle task */
#endif
#endif
#if OS_TASK_NAME_SIZE > 14
OSTaskNameSet(OS_TASK_STAT_PRIO, (INT8U *)"uC/OS-II Stat", &err);
#else
#if OS_TASK_NAME_SIZE > 7
OSTaskNameSet(OS_TASK_STAT_PRIO, (INT8U *)"OS-Stat", &err);
#endif
#endif
}
#endif
其中任务的处理函数如下:
/*
*********************************************************************************************************
* STATISTICS TASK
*
* Description: This task is internal to uC/OS-II and is used to compute some statistics about the
* multitasking environment. Specifically, OS_TaskStat() computes the CPU usage.
* CPU usage is determined by:
*
* OSIdleCtr
* OSCPUUsage = 100 * (1 - ------------) (units are in %)
* OSIdleCtrMax
*
* Arguments : parg this pointer is not used at this time.
*
* Returns : none
*
* Notes : 1) This task runs at a priority level higher than the idle task. In fact, it runs at the
* next higher priority, OS_TASK_IDLE_PRIO-1.
* 2) You can disable this task by setting the configuration #define OS_TASK_STAT_EN to 0.
* 3) You MUST have at least a delay of 2/10 seconds to allow for the system to establish the
* maximum value for the idle counter.
*********************************************************************************************************
*/
#if OS_TASK_STAT_EN > 0
void OS_TaskStat (void *p_arg)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
(void)p_arg; /* Prevent compiler warning for not using 'p_arg' */
while (OSStatRdy == OS_FALSE) {
OSTimeDly(2 * OS_TICKS_PER_SEC / 10); /* Wait until statistic task is ready */
}
OSIdleCtrMax /= 100L;
if (OSIdleCtrMax == 0L) {
OSCPUUsage = 0;
(void)OSTaskSuspend(OS_PRIO_SELF);
}
for (;;) {
OS_ENTER_CRITICAL();
OSIdleCtrRun = OSIdleCtr; /* Obtain the of the idle counter for the past second */
OSIdleCtr = 0L; /* Reset the idle counter for the next second */
OS_EXIT_CRITICAL();
OSCPUUsage = (INT8U)(100L - OSIdleCtrRun / OSIdleCtrMax);
OSTaskStatHook(); /* Invoke user definable hook */
#if (OS_TASK_STAT_STK_CHK_EN > 0) && (OS_TASK_CREATE_EXT_EN > 0)
OS_TaskStatStkChk(); /* Check the stacks for each task */
#endif
OSTimeDly(OS_TICKS_PER_SEC / 10); /* Accumulate OSIdleCtr for the next 1/10 second */
}
}
#endif
在空闲和统计任务中可以完成自定需要处理的数据。比如任务创建的个数,资源的使用情况等。