金士顿 2280:uC/OS-II实验程序之二(消息邮箱)
uC/OS-II实验程序之二(消息邮箱)
分类: 嵌入式操作系统(Embedded Operating System) C/C++ 2004-08-05 17:14 2561人阅读 评论(0) 收藏 举报消息邮箱是进程通讯中的重要工具,在本例中,使用一个POST任务来发送消息(一个字符,从A-Z),用一个PEND来接收消息。注意,在本例中发送任务是每个时钟周期都发送,而接收任务每3个时钟周期才接收一次。所以,一定会有某些字符不能接收到。
由于消息邮箱(长度为1的消息队列)是消息队列的特殊情况,所以在以后的消息队列程序中还将实验这种情况,看是否会有字符丢失。
/*
*********************************************************************************************************
* uC/OS-II
* The Real-Time Kernel
*
* (c) Copyright 2004, Yuan Fei, Hefei University of Technology
* All Rights Reserved
*
*
*
* Filename : test.c
* Programmer(s): yuan fei
* DESCRIPTION : This file illustrate the usage of Message Mailbox.
*
*********************************************************************************************************
*/
#include "includes.h"
/*
*********************************************************************************************************
* TYPE
*********************************************************************************************************
*/
typedef char MESSAGE; /* 消息为单个字符 */
/*
*********************************************************************************************************
* CONSTANTS
*********************************************************************************************************
*/
#define TASK_STK_SIZE 256 /* Size of each task's stacks (# of WORDs) */
#define N_TASKS 2 /* Number of identical tasks */
/*
*********************************************************************************************************
* VARIABLES
*********************************************************************************************************
*/
OS_STK TaskStk[N_TASKS][TASK_STK_SIZE]; /* Tasks stacks */
OS_STK TaskStartStk[TASK_STK_SIZE];
OS_EVENT *Mailbox;
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
void TaskStart(void *data); /* Function prototypes of Startup task */
static void MboxPend(void *data); /* 等待字符的进程 */
static void MboxPost(void *data); /* 发送字符的进程 */
/*
*********************************************************************************************************
* MAIN
*********************************************************************************************************
*/
void main (void)
{
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); /* Clear the screen */
OSInit(); /* Initialize uC/OS-II */
PC_DOSSaveReturn(); /* Save environment to return to DOS */
PC_VectSet(uCOS, OSCtxSw); /* Install uC/OS-II's context switch vector */
OSTaskCreate(TaskStart, (void *)0, &TaskStartStk[TASK_STK_SIZE - 1], 0);
OSStart(); /* Start multitasking */
}
/*
*********************************************************************************************************
* STARTUP TASK
*********************************************************************************************************
*/
void TaskStart (void *pdata)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT16S key;
pdata = pdata; /* Prevent compiler warning */
OS_ENTER_CRITICAL();
PC_VectSet(0x08, OSTickISR); /* Install uC/OS-II's clock tick ISR */
PC_SetTickRate(OS_TICKS_PER_SEC); /* Reprogram tick rate */
OS_EXIT_CRITICAL();
Mailbox = OSMboxCreate((void *) 0);
OSTaskCreate(MboxPost, 0, &TaskStk[0][TASK_STK_SIZE - 1], 2);
OSTaskCreate(MboxPend, 0, &TaskStk[1][TASK_STK_SIZE - 1], 3);
for (;;) {
if (PC_GetKey(&key) == TRUE) { /* See if key has been pressed */
if (key == 0x1B) { /* Yes, see if it's the ESCAPE key */
PC_DOSReturn(); /* Return to DOS */
}
}
OSTimeDlyHMSM(0, 0, 1, 0); /* Wait one second */
}
}
static void MboxPost (void *pdata)
{
MESSAGE msg;
for (msg = 'A'; msg <= 'Z'; msg++){
OSMboxPost(Mailbox, &msg);
OSTimeDly(1);
if (msg == 'Z'){
msg = 'A';
}
}
}
static void MboxPend (void *pdata)
{
MESSAGE msg;
INT16U i;
INT8U err;
for (i = 0;; ++i){
msg = *(MESSAGE*)OSMboxPend(Mailbox, 0, &err);
PC_DispChar(i % 80, i / 80, msg, DISP_FGND_WHITE);
OSTimeDly(3);
if (i > 2000){
i = 0;
}
}
}