您的位置:首页 > 房产 > 家装 > FreeRTOS和UCOS操作系统使用笔记

FreeRTOS和UCOS操作系统使用笔记

2025/1/9 4:32:49 来源:https://blog.csdn.net/weixin_42107504/article/details/140158407  浏览:    关键词:FreeRTOS和UCOS操作系统使用笔记

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

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com