logo资料库

uC/OS入门笔记.doc

第1页 / 共4页
第2页 / 共4页
第3页 / 共4页
第4页 / 共4页
资料共4页,全文预览结束
uC/OS-II(miu 扣丝兔) MicroC/OS-II The-Time Kernel 微控制器操作系统版本 2 是一个多任务的实时内核,允许建立多达 63 个用户任务。 uC/OS-II 终于在 STM32 上跑起 一切函数都要从 main()说起 一进来,挡在前面的是函数 OSIinit(): 其实吧,拉伯罗斯先生给函数起名字都是很讲究的,让我们理解下这个函数函数名字,OS =操作系统,Iinit=初始化,意思就是进行操作系统初始化。到底初始化了什么东东呢? 正如你要盖一座大厦之前,你要设置好一砖一瓦,一水泥一钢筋。所以在使用 ucosII 提供的 任何功能之前,必须调用 OSIinit 函数。 它调用了各种初始化,各种清空,各种裸~~ 它最重要的是它建立了两个任务: 空闲任务――没有任务时候运行的空任务。 统计任务――计算 CPU 的利用率,呵呵,想起了 XP 的任务管理器 (*task)(void *p_arg), 下面这个函数可以吓得人蛋都碎掉 OSTaskCreateExt(……………….): 你翻遍谭浩强大哥的那本 C 程序设计,也找不出这么变态的函数,里面参数都写了快三行 了,所以我只能无耻且无奈的以点点点代替之。 函数原型奉上~~ INT8U OSTaskCreateExt (void void *p_arg, OS_STK *ptos, prio, INT8U INT16U id, OS_STK *pbos, INT32U void INT16U stk_size, *pext, opt) { } 函数的功能是创建一个任务, 可以看到这里有 9 个参数,让我们一个个分析 task 是指向该任务运行的函数代码的指针(任务的代码函数) p_arg 是指向任务初始化数据的指针(任务传递的参数) ptos 是任务的堆栈栈顶 TOS,因为每个任务都有各自的堆栈空间,每个每个堆栈容量可以 单独指定(任务的堆栈) prio 是指定建立任务的优先级,值越小,优先级越高,说过 ucos2 可以建立多达 63 个用户 任务。必须给这些任务分配一个独一无二的(0~62)的优先级(任务的优先级别) id 是这个任务的 ID 即它的身份证号码(ID 号)
pbos 是任务的栈底指针(堆栈的底部) stk_size 堆栈的容量(堆栈的容量) pext 需要一个指向用户定义的 TCB 扩展数据结构的指针。如 cpu 是浮点计数器的时候 opt 其他选项有(选其他项) OS_TASK_OPT_STK_CHK 允许堆栈检查 OS_TASK_OPT_STK_CLR 清空任务创建时的栈 OS_TASK_OPT_SAVE_FP 如果 cpu 是浮点计数器的时候,上下文切换的时候保存 返回情况 OS_ERR_NONE 成功 OS_PRIO_EXIT 优先级存在了 OS_ERR_PRIO_INVALID 优先级超过设定的最大值 OS_ERR_TASK_CREATE_ISR 从中断中创建任务了 呼呼,终于把这该死的程序分析完了,正所谓万事俱备,只欠东风 接下来,开始任务调度了 OSStart() 这个函数将判断所有建立的任务中哪个任务是最重要的(优先级最高),并开始运行这个任 务; 实际应用: OSTaskCreateExt( App_TaskStart, (void *) 0, (OS_STK APP_TASK_START_PRIO, *) &App_TaskStartStk[APP_TASK_START_STK_SIZE - 1], APP_TASK_START_PRIO, (OS_STK *) &App_TaskStartStk[0], APP_TASK_START_STK_SIZE , (void *) 0, OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR ); 我们创建了一个叫 App_TaskStart,系统的第一个任务,负责开 OS 时钟,建立其他任务。没 有 初始 化数 据 ,分 配 堆栈 ,指 定 栈顶 , 任务 优先 级 ,ID 和 任务 优先 级 别是 相 同的 值 (APP_TASK_FLICKER_PRIO 5),确定栈底指针,这是任务堆栈检查的时候要用到的, 栈的大小,没有拓展 TCB,选项是允许堆栈检查,并清空任务创建时的栈。 当运行完 OSStart();main 函数就这样没了~~,正如一些东西,你还没感受它存在,就 消失了。那往哪运行了?我们既然创建了 App_TaskStart 的任务,就有这个函数~ static { void App_TaskStart(void* p_arg) p_arg = p_arg; /* 初始化 OS 时钟 */ OS_CPU_SysTickInit(); /* 统计任务 */ #if (OS_TASK_STAT_EN > 0) OSStatInit(); #endif OSTaskCreateExt(
App_TaskFLICKER, (void *) 0, (OS_STK APP_TASK_FLICKER_PRIO, *) &App_TaskFLICKERStk[APP_TASK_FLICKER_STK_SIZE - 1], APP_TASK_FLICKER_PRIO, (OS_STK *) &App_TaskFLICKERStk[0], APP_TASK_FLICKER_STK_SIZE , (void *) 0, OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR ); // 建立闪灯线程 /* 初始化外设 */ BSP_Init(); // 开启 CPU 外设 while (1) { OSTaskSuspend(OS_PRIO_SELF); // 挂起任务 } } 环中环,套中套,第一个任务,初始化了该初始化的,然后又依葫芦画瓢,又创建一个线程, 最后突然出现了一个莫名奇妙的函数,挂起任务?OSTaskSuspend(OS_PRIO_SELF); 其实,这里是挂起了 SELF,就是自身,App_TaskStart。任务挂起后,系统会重新进行任务 调度,运行下一个优先级最高的就绪任务。 得,这就相当于儿子在荡秋千,需要爸爸给于启动的条件。App_TaskStart 就是爸爸,挂起 就是秋千启动后,你的手不能老不松开啊,这明显影响儿子荡秋千的心情,且能不能荡的起 来还是一回事呢~ 好了,下面来看看儿子~~App_TaskFLICKER 函数 OSTaskCreateExt( App_TaskFLICKER, (void *) 0, (OS_STK APP_TASK_FLICKER_PRIO, APP_TASK_FLICKER_PRIO, (OS_STK *) &App_TaskFLICKERStk[0], APP_TASK_FLICKER_STK_SIZE , (void *) 0, OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR ); // 建立闪灯线程 我们又创建了一个叫 App_TaskFLICKER,没有初始化数据,分配堆栈,指定栈顶,任务优 先级,ID 和任务优先级别是相同的值(APP_TASK_FLICKER_PRIO 6),确定栈底指针, 栈的大小,没有拓展 TCB,选项是允许堆栈检查,并清空任务创建时的栈。 &App_TaskFLICKERStk[APP_TASK_FLICKER_STK_SIZE 1], *) - void App_TaskFLICKER(void* p_arg) static { INT8U i; p_arg = p_arg;
while (1) { for(i = 0 ; i < 2; i++){ LED1_ON_OFF(i); OSTimeDlyHMSM(0,0,1,0); // 延时一秒 } } } 任务函数就比较让人惬意了,可以看到传递的参数是 p_arg 其实我们这里并没有用到它,所以,为了避免编译器报错,说我们花了国家的土地,盖了一 个茅房,却不进去如厕,会被严惩的;所以只能有事没事的进去蹲蹲~~p_arg = p_arg;(没 有实际意义的一句话,仅仅为了避免编译器报警) 任务就是一个无限死循环,它的生命周期是要交给内核来定夺的 这里是 LED 灯每隔 1 秒闪烁一次的程序。烧到板上,看到那灯很嚣张的一亮一灭的时候, 心情不免小小激动了~~
分享到:
收藏