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_MsgOSQCreate ( (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);
}