uC/OS-II源码分析(二)

在真正开始分析源代码前,先来看使用 uC/OS-II 的 三个例子

1)使用信号量

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> #define TASK_STK_SIZE512/*每个任务堆栈的大小(以字计算)*/
#define N_TASKS10/*任务数*/

OS_STKTaskStk[N_TASKS][TASK_STK_SIZE];
/* 任务堆栈 */
OS_STKTaskStartStk[TASK_STK_SIZE];
// 开始任务的堆栈
char TaskData[N_TASKS]; /* 传给每个任务的数据 */
OS_EVENT
* RandomSem; // 互斥型信号量

void main( void )
{
PC_DispClrScr(DISP_FGND_WHITE
+ DISP_BGND_BLACK); /* 清空屏幕 */

OSInit();
/* 初始化uC/OS-II */

PC_DOSSaveReturn();
/* 保存环境以便稍后可以返回DOS环境 */
PC_VectSet(uCOS,OSCtxSw);
/* 设置uC/OS-II的切换处理函数 */
RandomSem
= OSSemCreate( 1 ); /* 建立一个信号量 */
OSTaskCreate(TaskStart,(
void * ) 0 , & TaskStartStk[TASK_STK_SIZE - 1 ], 0 ); // 创建第一个任务,优先级设置为最大值
OSStart(); /* 开始多任务 */
}
void TaskStart( void * pdata)
{
#if OS_CRITICAL_METHOD==3/*为CPU的状态寄存器分配内存*/
OS_CPU_SRcpu_sr;
#endif
char s[ 100 ];
INT16Skey;
pdata
= pdata; /* 这步是为了防止编译错误 */
TaskStartDispInit();
/* 初始化显示屏 */
OS_ENTER_CRITICAL();
PC_VectSet(
0x08 ,OSTickISR); /* 替换机器的时钟中断函数为uC/OS-II所需要的中断函数 */
PC_SetTickRate(OS_TICKS_PER_SEC);
/* 调整时钟频率 */
OS_EXIT_CRITICAL();
OSStatInit();
/* 初始化统计任务 */
TaskStartCreateTasks();
/* 创建其他任务 */
for (;;){
TaskStartDisp();


if (PC_GetKey( & key) == TRUE){ /* 是否按键 */
if (key == 0x1B ){ /* ESCAPE按下了 */
PC_DOSReturn();
/* 返回DOS */
}
}

OSCtxSwCtr
= 0 ; /* 切换次数计数器清零 */
OSTimeDlyHMSM(
0 , 0 , 1 , 0 ); /* 挂起秒,让给其他任务运行 */
}
}
static void TaskStartCreateTasks( void )
{
INT8Ui;
for (i = 0 ;i < N_TASKS;i ++ ){ /* 创建N_TASKS个任务 */
TaskData[i]
= ' 0 ' + i; /* 每个任务显示其数据 */
OSTaskCreate(Task,(
void * ) & TaskData[i], & TaskStk[i][TASK_STK_SIZE - 1 ],i + 1 );
}
}

void Task( void * pdata)
{
INT8Ux;
INT8Uy;
INT8Uerr;
for (;;){
OSSemPend(RandomSem,
0 , & err); /* 获取信号量 */
x
= random( 80 ); /* 计算X坐标 */
y
= random( 16 ); /* 计算Y坐标 */
OSSemPost(RandomSem);
/* 释放信号量 */
/* Displaythetasknumberonthescreen */
PC_DispChar(x,y
+ 5 , * ( char * )pdata,DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
OSTimeDly(
1 ); /* 挂起秒,让给其他任务运行 */
}
}
2007112201.jpg

2)使用消息邮箱

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
#define TASK_STK_SIZE512
#define TASK_START_ID0/*任务ID*/
#define TASK_CLK_ID1
#define TASK_1_ID2
#define TASK_2_ID3
#define TASK_3_ID4
#define TASK_4_ID5
#define TASK_5_ID6

#define TASK_START_PRIO10/*任务优先级*/
#define TASK_CLK_PRIO11
#define TASK_1_PRIO12
#define TASK_2_PRIO13
#define TASK_3_PRIO14
#define TASK_4_PRIO15
#define TASK_5_PRIO16
OS_STKTaskStartStk[TASK_STK_SIZE];
OS_STKTaskClkStk[TASK_STK_SIZE];
OS_STKTask1Stk[TASK_STK_SIZE];
OS_STKTask2Stk[TASK_STK_SIZE];
OS_STKTask3Stk[TASK_STK_SIZE];
OS_STKTask4Stk[TASK_STK_SIZE];
OS_STKTask5Stk[TASK_STK_SIZE];
OS_EVENT
* AckMbox; /* 任务和使用的消息邮箱 */
OS_EVENT
* TxMbox;

void main( void )
{
OS_STK
* ptos;
OS_STK
* pbos;
INT32Usize;
PC_DispClrScr(DISP_FGND_WHITE);
OSInit();
PC_DOSSaveReturn();
PC_VectSet(uCOS,OSCtxSw);
PC_ElapsedInit();
ptos
= & TaskStartStk[TASK_STK_SIZE - 1 ];
pbos
= & TaskStartStk[ 0 ];
size
= TASK_STK_SIZE;
OSTaskStkInit_FPE_x86(
& ptos, & pbos, & size);
OSTaskCreateExt(TaskStart,
(
void * ) 0 ,
ptos,
TASK_START_PRIO,
TASK_START_ID,
pbos,
size,
(
void * ) 0 ,
OS_TASK_OPT_STK_CHK
| OS_TASK_OPT_STK_CLR);
OSStart();
}
void TaskStart( void * pdata)
{
#if OS_CRITICAL_METHOD==3
OS_CPU_SRcpu_sr;
#endif
INT16Skey;
pdata
= pdata;
TaskStartDispInit();
OS_ENTER_CRITICAL();
PC_VectSet(
0x08 ,OSTickISR);
PC_SetTickRate(OS_TICKS_PER_SEC);
OS_EXIT_CRITICAL();
OSStatInit();
AckMbox
= OSMboxCreate(( void * ) 0 ); /* 创建两个消息邮箱 */
TxMbox
= OSMboxCreate(( void * ) 0 );
TaskStartCreateTasks();
for (;;){
TaskStartDisp();

if (PC_GetKey( & key)){
if (key == 0x1B ){
PC_DOSReturn();
}
}
OSCtxSwCtr
= 0 ;
OSTimeDly(OS_TICKS_PER_SEC);
}
}
void Task1( void * pdata)
{
INT8Uerr;
OS_STK_DATAdata;
/* 任务堆栈数据 */
INT16Utime;
INT8Ui;
char s[ 80 ];
pdata
= pdata;
for (;;){
for (i = 0 ;i < 7 ;i ++ ){
PC_ElapsedStart();
err
= OSTaskStkChk(TASK_START_PRIO + i, & data); // 执行堆栈检查
time = PC_ElapsedStop();
if (err == OS_NO_ERR){
sprintf(s,
" %4ld%4ld%4ld%6d " ,
data.OSFree
+ data.OSUsed,
data.OSFree,
data.OSUsed,
time);
PC_DispStr(
19 , 12 + i,s,DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
}
}
OSTimeDlyHMSM(
0 , 0 , 0 , 100 ); /* 挂起mS */
}
}
void Task4( void * data)
{
char txmsg;
INT8Uerr;
data
= data;
txmsg
= ' A ' ;
for (;;){
OSMboxPost(TxMbox,(
void * ) & txmsg); /* 发消息给Task#5 */
OSMboxPend(AckMbox,
0 , & err); /* 等待Task#5的应答消息 */
txmsg
++ ; /* 下一个要发的消息数据 */
if (txmsg == ' Z ' ){
txmsg
= ' A ' ; /* 循环发送A-Z */
}
}
}
void Task5( void * data)
{
char * rxmsg;
INT8Uerr;
data
= data;
for (;;){
rxmsg
= ( char * )OSMboxPend(TxMbox, 0 , & err); /* 等待来自Task#4的数据 */
PC_DispChar(
70 , 18 , * rxmsg,DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDlyHMSM(
0 , 0 , 1 , 0 ); /* 挂起秒,让给其他任务运行 */
OSMboxPost(AckMbox,(
void * ) 1 ); /* 发送接收到数据的应答消息 */
}
}

运行结果:

2007112202.jpg

3)使用消息队列

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> #define TASK_STK_SIZE512
#define TASK_START_ID0
#define TASK_CLK_ID1
#define TASK_1_ID2
#define TASK_2_ID3
#define TASK_3_ID4
#define TASK_4_ID5
#define TASK_5_ID6
#define TASK_START_PRIO10
#define TASK_CLK_PRIO11
#define TASK_1_PRIO12
#define TASK_2_PRIO13
#define TASK_3_PRIO14
#define TASK_4_PRIO15
#define TASK_5_PRIO16
#define MSG_QUEUE_SIZE20/*消息队列大小*/
typedef
struct {
char TaskName[ 30 ];
INT16UTaskCtr;
INT16UTaskExecTime;
INT32UTaskTotExecTime;
}TASK_USER_DATA;
OS_STKTaskStartStk[TASK_STK_SIZE];
OS_STKTaskClkStk[TASK_STK_SIZE];
OS_STKTask1Stk[TASK_STK_SIZE];
OS_STKTask2Stk[TASK_STK_SIZE];
OS_STKTask3Stk[TASK_STK_SIZE];
OS_STKTask4Stk[TASK_STK_SIZE];
OS_STKTask5Stk[TASK_STK_SIZE];
TASK_USER_DATATaskUserData[
7 ];
OS_EVENT
* MsgQueue; /* 消息队列指针 */
void * MsgQueueTbl[ 20 ]; /* 消息存储 */
void main( void )
{
PC_DispClrScr(DISP_BGND_BLACK);
OSInit();
PC_DOSSaveReturn();
PC_VectSet(uCOS,OSCtxSw);
PC_ElapsedInit();
strcpy(TaskUserData[TASK_START_ID].TaskName,
" StartTask " );
OSTaskCreateExt(TaskStart,
(
void * ) 0 ,
& TaskStartStk[TASK_STK_SIZE - 1 ],
TASK_START_PRIO,
TASK_START_ID,
& TaskStartStk[ 0 ],
TASK_STK_SIZE,
& TaskUserData[TASK_START_ID],
0 );
OSStart();
}
void TaskStart( void * pdata)
{
#if OS_CRITICAL_METHOD==3
OS_CPU_SRcpu_sr;
#endif
INT16Skey;
pdata
= pdata;
TaskStartDispInit();
OS_ENTER_CRITICAL();
PC_VectSet(
0x08 ,OSTickISR);
PC_SetTickRate(OS_TICKS_PER_SEC);
OS_EXIT_CRITICAL();
OSStatInit();
MsgQueue
= OSQCreate( & MsgQueueTbl[ 0 ],MSG_QUEUE_SIZE); /* 创建消息队列,大小为 */
TaskStartCreateTasks();
for (;;){
TaskStartDisp();
if (PC_GetKey( & key)){
if (key == 0x1B ){
PC_DOSReturn();
}
}
OSCtxSwCtr
= 0 ;
OSTimeDly(OS_TICKS_PER_SEC);
}
}
void Task1( void * pdata)
{
char * msg;
INT8Uerr;
pdata
= pdata;
for (;;){
msg
= ( char * )OSQPend(MsgQueue, 0 , & err); // 从消息队列中取消息
PC_DispStr( 70 , 13 ,msg,DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDlyHMSM(
0 , 0 , 0 , 100 );
}
}
void Task2( void * pdata)
{
char msg[ 20 ];
pdata
= pdata;
strcpy(
& msg[ 0 ], " Task2 " );
for (;;){
OSQPost(MsgQueue,(
void * ) & msg[ 0 ]); // 发送消息到队列中
OSTimeDlyHMSM( 0 , 0 , 0 , 500 );
}
}
void Task3( void * pdata)
{
char msg[ 20 ];
pdata
= pdata;
strcpy(
& msg[ 0 ], " Task3 " );
for (;;){
OSQPost(MsgQueue,(
void * ) & msg[ 0 ]); // 发送消息到队列中
OSTimeDlyHMSM( 0 , 0 , 0 , 500 );
}
}
void Task4( void * pdata)
{
char msg[ 20 ];
pdata
= pdata;
strcpy(
& msg[ 0 ], " Task4 " );
for (;;){
OSQPost(MsgQueue,(
void * ) & msg[ 0 ]); // 发送消息到队列中
OSTimeDlyHMSM( 0 , 0 , 0 , 500 );
}
}
void OSTaskStatHook( void )
{
char s[ 80 ];
INT8Ui;
INT32Utotal;
INT8Upct;
total
= 0L ; /* TotalizeTOT.EXEC.TIMEforeachtask
for(i=0;i<7;i++){
total+=TaskUserData[i].TaskTotExecTime;
DispTaskStat(i);/*Displaytaskdata
}
if(total>0){
for(i=0;i<7;i++){/*Derivepercentageofeachtask
*/
pct
= 100 * TaskUserData[i].TaskTotExecTime / total;
sprintf(s,
" %3d%% " ,pct);
PC_DispStr(
62 ,i + 11 ,s,DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
}
}
if (total > 1000000000L ){ /* Resettotaltimecountersat1billion
for(i=0;i<7;i++){
TaskUserData[i].TaskTotExecTime=0L;
}
}
}

voidOSTaskSwHook(void)
{
INT16Utime;
TASK_USER_DATA*puser;
time=PC_ElapsedStop();/*Thistaskisdone
PC_ElapsedStart();/*Startfornexttask
puser=OSTCBCur->OSTCBExtPtr;/*Pointtouseddata
if(puser!=(TASK_USER_DATA*)0){
puser->TaskCtr++;/*Incrementtaskcounter
puser->TaskExecTime=time;/*Updatethetask'sexecutiontime
puser->TaskTotExecTime+=time;/*Updatethetask'stotalexecutiontime
}
}

运行结果:

2007112204.jpg
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值