嵌入式实时操作系统small RTOS51原理及应用 ----笔记 第七章 任务之间的通信和同步之消息队列

嵌入式实时操作系统small RTOS51原理及应用 ----笔记 第七章 任务之间的通信和同步之消息队列

Small_RTOS1.12.1\small_rtos\SerialIn

实现方式 类似于 信号量
主要是理解 循环队列

消息队列 应用场景

#define NBYTE           7
#define STARTBYTE1      0xf0
#define STARTBYTE2      0xf1
#define RECIVE_TASK_ID  0

uint8 Buf[NBYTE - 3];

uint8  SerialData[14];
void TaskA(void)
{
    uint8 data temp,temp1;
    uint8 Sum,i;


    OSQCreate(SerialData,14);

	OSQPend(&temp,SerialData,0);
	
        while (1)
        {
            if (OSQPend(&temp1,SerialData,20) == OS_Q_TMO)
            {
                goto start;
            }	
   	      }
 }


void TaskB(void)
{
    while (1)
    {
        OSWait(K_TMO,10);
        OSQPost(SerialData,0xf0);
        OSWait(K_TMO,10);
        OSQPost(SerialData,0xf1);
        OSWait(K_TMO,10);
        OSQPost(SerialData,0xf0);
        OSWait(K_TMO,10);
        OSQPost(SerialData,0xf0);
        OSWait(K_TMO,10);
        OSQPost(SerialData,0x00);
        OSWait(K_TMO,10);
        OSQPost(SerialData,0x00);
        OSWait(K_TMO,10);
        OSQPost(SerialData,0x3f);
    }
}
  

初始化消息队列 OSQCreate

OSQCreate

//输 入: Buf:为队列分配的存储空间地址
//SizeOfBuf:为队列分配的存储空间大小
// 输 出: NOT_OK:参数错误
//         OS_Q_OK:成功
//Buf[0]:队列中字节数,Buf[1]:Buf总长度,Buf[2]:出对端,Buf[3](,Buf[4]):等待队列任务列表

uint8 OSQCreate(uint8  *Buf, uint8 SizeOfBuf)
{
    OS_ENTER_CRITICAL();

    if ((SizeOfBuf >= 5) && (Buf != NULL))
    {
        Buf[0] = 0;                         /* 队列中消息数目           */
        Buf[1] = SizeOfBuf;           /* 消息队列占用内存字节数    */

        Buf[2] = 4;                         /* 将要出队的消息所在位置    */

        Buf[3] = 0;                         /* 消息队列的等待任务列表    */
        Buf[4] = 0;                         /* 任务数大于等于8时为等待任务列表的一部分, */
                                                  /* 否则为消息缓冲区         */

        OS_EXIT_CRITICAL();
        return OS_Q_OK;
    }
    else
    {
        OS_EXIT_CRITICAL();
        return NOT_OK;
    }

}

OSQPend 等待消息队列中的消息

函数名称: OSQPend
功能描述: 等待消息队列中的消息
输 入: Ret:返回的消息
Buf:指向队列的指针
Tick:等待时间
输 出: NOT_OK:参数错误
OS_Q_OK:收到消息
OS_Q_TMO:超时到
OS_Q_NOT_OK:无消息

uint8 OSQPend(uint8 data *Ret, uint8 OS_Q_MEM_SEL *Buf, uint8 Tick)
{
#ifdef __C51__
    uint8 data *cp;
#endif

    OS_ENTER_CRITICAL(); // 关闭中断
    
     /* 设置当前任务的超时时间         */
    OSWaitTick[OSRunningTaskID()] = Tick;      
                                             

/* 使用堆栈是为了使函数具有重入性 */
#ifdef __C51__
    SP++;
    *((uint8 data * data *)SP) = Ret;
#endif

/* 把任务加入等待任务队列 */
Buf[3] |= OSMapTbl[OSRunningTaskID()];

 while (Buf[0] == 0)             /* 消息队列中是否有消息 */
 {
    Buf[0]  =0  表示 没有数据
                
#ifdef __C51__
        SP = SP + sizeof(Buf);
        *((uint8  * data *)(SP + 1 - sizeof(Buf))) = Buf;
#endif

        OSClearSignal(OSRunningTaskID());   /* 任务进入等待状态 */
        OSSched();                          /* 运行下一个任务 */

#ifdef __C51__
        Buf = *((uint8 OS_Q_MEM_SEL * data *)(SP + 1 - sizeof(Buf)));
        SP = SP - sizeof(Buf);
#endif
                /* 任务再次运行,如果超时到,退出循环 */
        if (OSWaitTick[OSRunningTaskID()] == 0)
        {
            break;
        }
    } // end of while (Buf[0] == 0)
    

     /* 将任务从等待队列中清除(可以删除) */
     /*Buf[3]这个字节的每一位,对应一个任务*/
    Buf[3] &= ~OSMapTbl[OSRunningTaskID()];
    //如果是消息队列中,有消息   
    if (Buf[0] > 0)
    {
        /* 有,消息出队 */
        Buf[0]--;           /* 队列的消息数目减一 */
        /* 指向下一个出队位置 */
        Buf[2]++; // 出队消息指针
        
        /* Buf[1]消息队列占用内存字节数 */
        if (Buf[2] >= Buf[1] )
        {

            Buf[2] = 4;
        }
#ifdef __C51__
        cp = (uint8 data *)(*((uint8 data *)SP));
        SP--;
        *cp = Buf[Buf[2]];
#else
        *Ret = Buf[Buf[2]];
#endif
        OS_EXIT_CRITICAL();
        return OS_Q_OK;
    }
    else
    {
                /* 无,返回错误码 */
#ifdef __C51__
        SP--;
#endif

        OS_EXIT_CRITICAL();
        return OS_Q_TMO;
    }
}

OSWait(K_SIG,0) 应用场景

其中 : OSIntSendSignal(1) 和OSWait(K_SIG,0); 是对应的
TaskB 的 任务索引ID 等于 1

void comm(void) interrupt 4
{
    OS_INT_ENTER();
    if (RI == 1)
    {
        RI = 0;
#if EN_OS_Q_INT_POST > 0
        OSQIntPost(SerialData,SBUF);
#endif
#if EN_OS_Q_INT_POST_FRONT > 0
        OSQIntPostFront(SerialData,SBUF);
#endif

    }
    if (TI == 1)
    {
        TI = 0;
        OSIntSendSignal(1);
    }
    OSIntExit();
    
}


void TaskB(void)
{
    while (1)
    {
        OSWait(K_SIG,0);
        SBUF = 'O';
        OSWait(K_SIG,0);
        SBUF = 'K';
        OSWait(K_SIG,0);
        SBUF = '!';
        OSWait(K_SIG,0);
        SBUF = '\n';
        OSWait(K_SIG,0);
    } 
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值