完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
功能
μC/OS-II由Micrium公司提供,是一个可移植、可固化的、可裁剪的、占先式多任务实时内核,它适用于多种微处理器,微控制器和数字处理芯片(已经移植到超过100种以上的微处理器应用中)。同时,该系统源代码开放、整洁、一致,注释详尽,适合系统开发。 μC/OS-II已经通过联邦航空局(FAA)商用航行器认证,符合航空无线电技术委员会(RTCA)DO-178B标准。现在最新版的是μC/OS-III。 μC/OS-II可以大致分成核心、任务处理、时间处理、任务同步与通信,CPU的移植等5个部分。
二、基础知识 1、任务的创建 ①定义相关参数 //任务优先级 #define LED1_TASK_PRIO 5 //任务堆栈大小 #define LED1_STK_SIZE 128 //任务控制块 OS_TCB Led1TaskTCB; //任务堆栈 CPU_STK LED1_TASK_STK[LED1_STK_SIZE]; //任务函数 void led1_task(void *p_arg); ②创建任务 //创建LED1任务 OSTaskCreate((OS_TCB * )&Led1TaskTCB, (CPU_CHAR * )"led1 task", (OS_TASK_PTR )led1_task, (void * )0, (OS_PRIO )LED1_TASK_PRIO, (CPU_STK * )&LED1_TASK_STK[0], (CPU_STK_SIZE)LED1_STK_SIZE/10, (CPU_STK_SIZE)LED1_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); ③编写任务函数 //led1任务函数 void led1_task(void *p_arg) { OS_ERR err; p_arg = p_arg; while(1) { LED1=~LED1; OSTimeDlyHMSM(0,0,0,200,OS_OPT_TIME_HMSM_STRICT,&err); //延时500ms } } 2、任务的挂起与恢复 在这里插入代码片//task1任务函数 void task1_task(void *p_arg) { u8 task1_num=0; OS_ERR err; CPU_SR_ALLOC(); p_arg = p_arg; POINT_COLOR = BLACK; OS_CRITICAL_ENTER(); LCD_DrawRectangle(5,110,115,314); //画一个矩形 LCD_DrawLine(5,130,115,130); //画线 POINT_COLOR = BLUE; LCD_ShowString(6,111,110,16,16,"Task1 Run:000"); OS_CRITICAL_EXIT(); while(1) { task1_num++; //任务1执行次数加1 注意task1_num1加到255的时候会清零!! LED0= ~LED0; printf("任务1已经执行:%d次rn",task1_num); if(task1_num==5) { OSTaskSuspend((OS_TCB*)&Task2_TaskTCB,&err);//任务1执行5次后挂起任务2 printf("任务1挂起了任务2!rn"); } if(task1_num==10) { OSTaskResume((OS_TCB*)&Task2_TaskTCB,&err); //任务1运行10次后恢复任务2 printf("任务1恢复了任务2!rn"); } LCD_Fill(6,131,114,313,lcd_discolor[task1_num%14]); //填充区域 LCD_ShowxNum(86,111,task1_num,3,16,0x80); //显示任务执行次数 OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1s } } 3、任务同步 ①定义信号量 OS_SEM MY_SEM; //定义一个信号量,用于访问共享资源 ②在开始任务中创建信号量 OSSemCreate ((OS_SEM* )&MY_SEM, //创建一个信号量 (CPU_CHAR* )"MY_SEM", (OS_SEM_CTR)1, (OS_ERR* )&err); ③使用信号量 //led0任务函数 void led0_task(void *p_arg) { OS_ERR err; p_arg = p_arg; while(1) { OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); //请求信号量 LED0=~LED0; // share_resource=share_resource+1; // printf("任务1执行次数:%drn",share_resource); // delay_ms(1000); // OSSemPost (&MY_SEM,OS_OPT_POST_1,&err); //发送信号量 OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时500ms } } //led1任务函数 void led1_task(void *p_arg) { OS_ERR err; p_arg = p_arg; while(1) { LED1=~LED1; OSSemPost (&MY_SEM,OS_OPT_POST_1,&err); // OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); //请求信号量 // share_resource=share_resource+1; // printf("任务2执行次数:%drn",share_resource); //delay_ms(2000); //发送信号量 OSTimeDlyHMSM(0,0,2,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时500ms } } 4、消息传递 ①定义消息队列 #define KEYMSG_Q_NUM 1 //按键消息队列的数量 #define DATAMSG_Q_NUM 4 //发送数据的消息队列的数量 OS_Q KEY_Msg; //定义一个消息队列,用于按键消息传递,模拟消息邮箱 OS_Q DATA_Msg; //定义一个消息队列,用于发送数据 ②创建消息队列 //创建消息队列KEY_Msg 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, (OS_ERR* )&err); ③任务函数 //定时器1的回调函数 void tmr1_callback(void *p_tmr,void *p_arg) { u8 *pbuf; static u8 msg_num; OS_ERR err; pbuf = mymalloc(SRAMIN,10); //申请10个字节 if(pbuf) //申请内存成功 { msg_num++; sprintf((char*)pbuf,"ALIENTEK %d",msg_num); //发送消息 OSQPost((OS_Q* )&DATA_Msg, (void* )pbuf, (OS_MSG_SIZE)10, (OS_OPT )OS_OPT_POST_FIFO, (OS_ERR* )&err); if(err != OS_ERR_NONE) { myfree(SRAMIN,pbuf); //释放内存 OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //停止定时器1 tmr1sta = !tmr1sta; LCD_ShowString(10,150,100,16,16,"TMR1 STOP! "); } } } //主任务的任务函数 void main_task(void *p_arg) { u8 key,num; OS_ERR err; u8 *p; while(1) { key = KEY_Scan(0); //扫描按键 if(key) { //发送消息 OSQPost((OS_Q* )&KEY_Msg, (void* )&key, (OS_MSG_SIZE)1, (OS_OPT )OS_OPT_POST_FIFO, (OS_ERR* )&err); } num++; if(num%10==0) check_msg_queue(p);//检查DATA_Msg消息队列的容量 if(num==50) { num=0; LED0 = ~LED0; } OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_PERIODIC,&err); //延时10ms } } //按键处理任务的任务函数 void Keyprocess_task(void *p_arg) { u8 num; u8 *key; OS_MSG_SIZE size; OS_ERR err; while(1) { //请求消息KEY_Msg key=OSQPend((OS_Q* )&KEY_Msg, (OS_TICK )0, (OS_OPT )OS_OPT_PEND_BLOCKING, (OS_MSG_SIZE* )&size, (CPU_TS* )0, (OS_ERR* )&err); switch(*key) { case WKUP_PRES: //KEY_UP控制LED1 LED1 = ~LED1; break; case KEY2_PRES: //KEY2控制蜂鸣器 BEEP = ~BEEP; break; case KEY0_PRES: //KEY0刷新LCD背景 num++; LCD_Fill(126,111,233,313,lcd_discolor[num%14]); break; case KEY1_PRES: //KEY1控制定时器1 tmr1sta = !tmr1sta; if(tmr1sta) { OSTmrStart(&tmr1,&err); LCD_ShowString(10,150,100,16,16,"TMR1 START!"); } else { OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //停止定时器1 LCD_ShowString(10,150,100,16,16,"TMR1 STOP! "); } break; } } } //显示消息队列中的消息 void msgdis_task(void *p_arg) { u8 *p; OS_MSG_SIZE size; OS_ERR err; while(1) { //请求消息 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); myfree(SRAMIN,p); //释放内存 OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延时1s } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1627 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1550 浏览 1 评论
984 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
688 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1601 浏览 2 评论
1867浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
650浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
518浏览 3评论
536浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
506浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 08:19 , Processed in 0.504095 second(s), Total 45, Slave 38 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号