FreeRTOS使用示例
UCOS使用示例
信号量使用
信号量访问共享资源区/
OS_SEMMY_SEM; //定义一个信号量,用于访问共享资源
OSSemCreate ((OS_SEM* )&MY_SEM, //创建信号量,指向信号量
(CPU_CHAR* )"MY_SEM", //信号量名字
(OS_SEM_CTR )1, //信号量值为1,可以理解开始有个任务就可以请求到信号量
(OS_ERR* )&err);//错误码
void task1_task(void *p_arg)
{
OS_ERR err;
u8 task1_str[]="First task Running!";
//请求信号量,参数2:0为死等;参数3:表示信号量无效任务挂起等待信号量;参数4:时间戳
OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err);
memcpy(share_resource,task1_str,sizeof(task1_str));//向共享资源区拷贝数据
delay_ms(200);
printf("%s\r\n",share_resource); //串口输出共享资源区数据
OSSemPost(&MY_SEM,OS_OPT_POST_1,&err); //发送信号量
}
void task2_task(void *p_arg)
{
OS_ERR err;
u8 task2_str[]="Second task Running!";
OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); //请求信号量(3)
memcpy(share_resource,task2_str,sizeof(task2_str));//向共享资源区拷贝数据
delay_ms(200);
printf("%s\r\n",share_resource); //串口输出共享资源区数据
//OS_OPT_POST_1表示向信号量优先级高的任务发送信号量
OSSemPost(&MY_SEM,OS_OPT_POST_1,&err);//发送信号量
}
/信号量用于任务同步实验
OS_SEM SYNC_SEM; //定义一个信号量,用于任务同步
OSSemCreate ((OS_SEM* )&SYNC_SEM,//创建信号量,指向信号量
(CPU_CHAR* )"SYNC_SEM",//信号量名字
(OS_SEM_CTR )0, //信号量值为0
(OS_ERR* )&err); //错误码
void task1_task(void *p_arg)
{
OS_ERR err;
if(KEY_Scan(0)==WKUP_PRES){
OSSemPost(&SYNC_SEM,OS_OPT_POST_1,&err);//发送信号量
LCD_ShowxNum(150,111,SYNC_SEM.Ctr,3,16,0); //显示信号量值
}
}
void task2_task(void *p_arg)
{
OS_ERR err;
//OS_OPT_PEND_BLOCKING:表示信号量无效任务挂起等待信号量
//如是OS_OPT_POST_ALL 向等待该信号量的所有任务发送信号量。
OSSemPend(&SYNC_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); //请求信号量
LCD_ShowxNum(150,111,SYNC_SEM.Ctr,3,16,0); //显示信号量值
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err);//延时1s
}
内建信号量
//内建信号量///
void task1_task(void *p_arg)
{
OS_ERR err;
if(KEY_Scan(0) == WKUP_PRES){
//OS_OPT_POST_NONE:不指定特定的选项
OSTaskSemPost(&Task2_TaskTCB,OS_OPT_POST_NONE,&err);//使用系统内建信号量向任务task2发送信号量
LCD_ShowxNum(150,111,Task2_TaskTCB.SemCtr,3,16,0); //显示信号量值
}
}
void task2_task(void *p_arg)
{
OS_ERR err;
//参数1:超时时间,0为一直等待信号量;2:信号量被占用则挂起等待;3:时间戳
OSTaskSemPend(0,OS_OPT_PEND_BLOCKING, 0,&err);//请求任务内建的信号量
LCD_ShowxNum(150,111,Task2_TaskTCB.SemCtr,3,16,0);//显示任务内建信号量值
}
消息传递
消息队列相关函数
消息队列//
#define KEYMSG_Q_NUM 1 //按键消息队列的数量
#define DATAMSG_Q_NUM 4 //发送数据的消息队列的数量
OS_Q KEY_Msg; //定义一个消息队列,用于按键消息传递,模拟消息邮箱
OS_Q DATA_Msg; //定义一个消息队列,用于发送数据
void start_task(void *p_arg)
{//......
OSQCreate ( (OS_Q* )&KEY_Msg,//指向一个消息队列
(CPU_CHAR* )"KEY Msg",//消息队列名称
(OS_MSG_QTY )KEYMSG_Q_NUM, //消息队列长度,这里设置为 1
(OS_ERR* )&err); //错误码
//创建消息队列 DATA_Msg
OSQCreate ( (OS_Q* )&DATA_Msg, //指向一个消息队列
(CPU_CHAR* )"DATA Msg",//消息队列的名称
(OS_MSG_QTY )DATAMSG_Q_NUM,//消息队列的个数这里是4
(OS_ERR* )&err);//错误码
}
void tmr1_callback(void *p_tmr,void *p_arg)
{//......
sprintf((char*)pbuf,"ALIENTEK %d",msg_num);
//发送消息
OSQPost((OS_Q* )&DATA_Msg,//指向一个消息队列
(void* )pbuf, //指向要发送的内容void指针
(OS_MSG_SIZE )10, //要发送的消息大小,单位字节
(OS_OPT )OS_OPT_POST_FIFO,//发送消息操作类型,这里表示发送消息报错队列尾部
(OS_ERR* )&err); //错误码
}
void main_task(void *p_arg)
{
u8 key = KEY_Scan(0); //扫描按键
//发送消息
OSQPost((OS_Q* )&KEY_Msg,
(void* )&key,
(OS_MSG_SIZE )1,
(OS_OPT )OS_OPT_POST_FIFO,
(OS_ERR* &err);
u8 msgq_remain_size = DATA_Msg.MsgQ.NbrEntriesSize-DATA_Msg.MsgQ.NbrEntries;//消息队列剩余大小
sprintf((char*)p,"Total Size:%d",DATA_Msg.MsgQ.NbrEntriesSize);//显示 DATA_Msg 消息队列总的大小
}
void Keyprocess_task(void *p_arg)
{
u8 num;
u8 *key;
OS_MSG_SIZE size;
OS_ERR err;
key=OSQPend((OS_Q* )&KEY_Msg, //指向一个消息队列,整个函数反回的是指针消息数据
(OS_TICK )0, //指定时间没有接收到数据任务就被唤醒,0一直等
(OS_OPT )OS_OPT_PEND_BLOCKING,//一直等,直到接收到消息
(OS_MSG_SIZE* )&size,//接收消息的字节长度
(CPU_TS* )0,//指向一个时间戳
(OS_ERR* )&err);//错误码
}
void msgdis_task(void *p_arg)
{
u8 *p;
OS_MSG_SIZE size;
OS_ERR err;
p=OSQPend( (OS_Q* )&DATA_Msg,
(OS_TICK )0,
(OS_OPT )OS_OPT_PEND_BLOCKING,
(OS_MSG_SIZE* )&size;
(CPU_TS* )0,
(OS_ERR* )&err);
LCD_ShowString(5,270,100,16,16,p);
}
任务内建消息队列
#define TASK_Q_NUM 4 //任务内建消息队列的长度
void tmr1_callback(void *p_tmr,void *p_arg)
{//......
sprintf((char*)pbuf,"ALIENTEK %d",msg_num);
OSTaskQPost((OS_TCB* )&Msgdis_TaskTCB, //向任务msgdis_task发送消息
(void* )pbuf, //指向要发送的内容void指针
(OS_MSG_SIZE )10, //指定要发送消息的大小
(OS_OPT )OS_OPT_POST_FIFO,//发送消息报错在队列末尾
(OS_ERR* )&err);//错误码
}
void msgdis_task(void *p_arg)
{//......
u8 *p;
OS_MSG_SIZE size;
OS_ERR err;
p=OSTaskQPend((OS_TICK )0, //超时时间没有接收到数据任务就被唤醒
(OS_OPT )OS_OPT_PEND_BLOCKING, //一直等待,直到接收到消息
(OS_MSG_SIZE* )&size, //消息的大小
(CPU_TS* )0, //时间戳
(OS_ERR* )&err ); //错误码
LCD_ShowString(40,270,100,16,16,p);//P为接收到的数据指针
}
事件标志组
事件标志组//
#define KEY0_FLAG 0x01
#define KEY1_FLAG 0x02
#define KEYFLAGS_VALUE 0X00
OS_FLAG_GRP EventFlags; //定义一个事件标志组
void start_task(void *p_arg)
{//......
OSFlagCreate((OS_FLAG_GRP* )&EventFlags, //指向事件标志组
(CPU_CHAR* )"Event Flags", //名字
(OS_FLAGS )KEYFLAGS_VALUE, //事件标志组初始值
(OS_ERR* )&err); //错误码
}
//向事件标志组 EventFlags 发送标志
void main_task(void *p_arg)
{//......
//按下按键1发送
flags_num=OSFlagPost((OS_FLAG_GRP*)&EventFlags,//指向事件标志组
(OS_FLAGS )KEY0_FLAG,//决定哪些位清零和置位
(OS_OPT )OS_OPT_POST_FLAG_SET,//对位进行置位操作,也可清零
(OS_ERR* )&err);//返回错误码
//按下按键2发送
//向事件标志组 EventFlags 发送标志
flags_num=OSFlagPost((OS_FLAG_GRP*)&EventFlags,
(OS_FLAGS )KEY1_FLAG,
(OS_OPT )OS_OPT_POST_FLAG_SET,
(OS_ERR* )&err);
}
void flagsprocess_task(void *p_arg)
{//......
OS_ERR err;
//等待事件标志组
OSFlagPend((OS_FLAG_GRP* )&EventFlags, //指向事件标准组
(OS_FLAGS )KEY0_FLAG+KEY1_FLAG,//等待 bit0和bit1时,值就为 0X03。
(OS_TICK )0,//等待超时时间,为0则一直等待下去
(OS_OPT )OS_OPT_PEND_FLAG_SET_ALL+\//多种配置模式:当前配置为等待所有位
OS_OPT_PEND_FLAG_CONSUME,//保留事件标志的状态
(CPU_TS* )0,//时间戳
(OS_ERR* )&err);//返回错误码
printf("事件标志组 EventFlags 的值:%d\r\n",EventFlags.Flags);
}