2023年12月10日发(作者:对学生会的建议)
uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
uCOS 学习随笔 StepbyStep‐1 ——构建模板(基于STM32控制的第四代圆梦小车) 一、 序 基于第四代圆梦小车 —— FIRA 设计了一个使用STM32的控制板(详细介绍见项目中的说明: Introduction B ‐ Hardware of the Smart )。 既然硬件从51升级到ARM,软件也应该相应升级,似乎不能再编写那种简单的轮询调度程序,也应该相应升级到基于操作系统编程。 按STM32的规模和性能,以及小车的控制需求,实时多任务操作系统 uCOSII 应该是不二的选择,不论从其性能和功能考虑,还是从学习角度考虑,uCOSII 都很适合。 首先,它是开源的,有丰富的资源。
其次,它是可靠的,符合正式的工业控制、产品设计需求。
小车所面对的是那些学习相关专业的大学生,作为他们学习的辅助工具,趣味性只是为了降低学习的枯燥性,不是目的。他们借助这个平台是为了积攒应付未来工作的能力,所以,学习内容的实用性是必须考虑的。 本人从未基于操作系统编写嵌入式程序。 开始使用 MCU 的时候,MCU 的内存太小,256字节 RAM ,2K字节 ROM,能勉强把程序装入就不错了,连 C 语言都不敢选择。 而且,那时好像也没有 RTOS(Real Time Operation System),或者是由于信息交流渠道匮乏,不知道有 RTOS。 既然我提供了这个平台,也借此机会尝试一下,和大家一起学习使用 uCOSII。(从单片机应用升级为嵌入式应用 ^_^) 第 1 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
二、Step1想要得到什么?(需求分析) 第一步我想得到的是: 1) 如何建立一个基于 uCOSII 的编程环境(目录、文件组织); 2) 如何基于IDE(IAR或RvMDK)建立一个工程,能够产生可以运行的程序; 3) 得到一个“干净的”、可以作为模板的uCOSII程序组(Project); 4) 通过上述过程初步理解在 uCOSII 下如何编写应用程序。 之所以要把“如何建立……”作为需求,而不是找一个现成的模板或示例程序修改、添加自己的功能,是因为看了许多这种程序,感觉“极不可靠”!因为程序中有太多的东西不知道为何而存在?不知道为何而被注释掉?似乎这些东西都像“定时炸弹”,早晚会给你的程序带来麻烦。 同时,也给自己理解程序的构成和运行机制带来困扰,既然是学习,就应该知其然、知其所以然,否则也谈不上“掌握”,更不敢在日后的工作中应用(如果是打工,也许还敢试试,如果是用自己的钱做产品、项目,我想你一定不敢用),如此则和做此事的初衷相悖了。 三、如何入手? uCOS的书有很多,也看了许多,但多数都是解析操作系统本身的,或者是如何移植,鲜有书籍、资料教你如何在操作系统下编程。 实际上,对于学习者,特别是初学者,更多需要的是学会如何在一个移植好的系统下编程,等到能基于操作系统实现自己的功能后,才会有心思去探究操作系统是如何在自己的
MCU 上运行的(移植),以及那些神秘的系统功能是如何实现的(了解系统函数及运行机制)。 而且这种探究也是有选择性的,首先是自己用到的功能才有兴趣去研究,否则如坠云雾。其次,取决于自己所扮演的角色,如果只是学习一下,那只需泛泛了解,有个定性的认识即第 2 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
可。如果要用于产品,那可能要深究,吃透其源代码,以保证产品的可靠和高效。
所以,要想学习有效,学习的方式首先要“正确”。 在编程理念上,人们已经接受了“面向对象”的思维方式,并且承认了其优越之处。
可在学习方式上似乎并未接受,至少大多数书籍还是基于“过程”的,目前所倡导的“任务驱动”(或者称之为“项目驱动”)模式似乎未被响应,而所谓“任务驱动”我觉得从实质上讲类似于编程中的“面向对象”概念。 “面向对象”核心是将编程的关注点放在要实现的功能上,而非实现功能的方式。 “任务驱动”核心是将学习的关注点放在要完成的任务上,而非完成任务的技能。 “面向对象”的优点源于这种思维方式转变带来了逻辑关系的清晰,从而使程序易于理解,带来的所有好处我认为都源于“易于理解”,如可移植性、可靠性、便于多人合作等。 而“任务驱动”同样也是得益于“易于理解”!(使用OS编程也是为了“易于理解”) 以往的“教”和“学”都是先传授知识、技能,后让学生使用之。可痛苦在于,这些知识、技能是前人为了解决某些问题而创建的,准确的说应该是解决问题后抽象出来的。学生们却要先把抽象的“记住”、“理解”,“暂存”后再去找机会用。想象一下,学的过程会有多“枯燥”,更可悲的是,到需要用时,“暂存”的东西找不到了 。 人通常对于明确目标的事情有较强的兴趣,而且目标越近,动力越大,越亢奋。对于不知为何而做的事很难投入,通常是三心二意应付了之。目前的大学多数是这个状况。 所谓“任务驱动”就是先明确目标,再去学习实现目的所需的知识和技能。这样学生在整个学习过程中都会主动去思考,不断斟酌正在学的东西可以怎样帮助自己实现目标。此时,你想让他走神都难。 所以,本学习过程尝试采用“任务驱动”方式。首先要确定一个合适的目标作为学习的素材,目标要可行、能提起兴趣,否则无异于没有。 第 3 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
我所选择的目标是用 STM32去控制一个小车。小车控制涵盖了数字输出输入、模拟输入、定时器应用、通讯应用等,应该说嵌入式控制常用的知识均已包含。 因为电机驱动,转动检测、电机电流检测、通讯等需求同时存在,而且这些任务都有响应时间要求,uCOS 的实时多任务特征正好可以得到应用。 小车可以扩展,控制板有I2C接口,很多传感器都带。但那是在小车控制自如后的事了。 本系列文章就准备在这个基础上逐渐深入。 四、初步规划 从03年开始关注 uCOSII ,买了邵老师的书。真正开始看是08年,我的第二代小车推出STM32扩展版之后。晕晕乎乎将书看完,结果还是无从下手,半途而废。 这次重新启动是因为第四代小车没有设计51的控制器,为了演示只能编写STM32的控制程序。 为避免再次夭折,强迫自己不再为了销售而编写不带系统的示例程序。那样虽很快捷,借助于ST的库,初始化好硬件,直接使用原来基于51的C程序即可。 可如果那样,或许就没有动力和压力去“折磨”自己,尝试在uCOSII下编程了。不过这次我决定更章易辙,从应用入手,不再纠缠于系统本身。 1)买一个移植成功的学习板作为参考(我买的是“奋斗STM32”),期望少走些弯路。 2)买了本《基于嵌入式实时操作系统的程序设计技术》,期待得到系统的指引。 3)从uCOS的官网(/page/home)下载最新的uCOS源程序及资料。 4)以驱动小车控制板上唯一的LED为任务,自己构建编程环境和工程,作为日后深入的基础。 因为51我是用Keil的,所以ARM决定还是用Keil,减小难度。 第 4 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
五、实施 5.1 准备工作
uCOS官网上有移植好的 Cortex‐M3 上的 uCOSII,程序包为: Micrium‐ST‐uCOS‐II‐LCD‐ 下载安装后,里面有uCOS源程序、ST库、基于ST学习板的示例程序、相应的说明。 看了若干资料,觉得最有价值莫过于从官网上下载的手册: AN1018 :µC/OSII and the ARM Cortex‐M3 Processors 特别是其中的这张图: 第 5 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
对照ReadMe 文件中的目录说明: 第 6 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
结合“程序关系图”、“目录文件说明”,浏览一下相关内容,那张“程序关系图”最好能映射在脑中,对理解、构建程序极为有益! 通过浏览,在脑中形成一个uCOS实现的框架,此时不必了解细节。 再把示例程序在IDE中打开编译、运行看看,因为我没有ST的学习板,就以奋斗STM32板的示例为参考。 这一步主要是为了验证IDE环境是否正确,因为示例的工程是正确的,如果此时有问题应出在IDE环境安装环节。如果开始就建立自己的工程,出现障碍则无法判断。 这次看这些文件似乎有些感觉,不知道是不是那些似懂非懂的阅读从量变到质变了。 不过回想学计算机的经历,似乎每次学习新的东西都要有个“从混沌的积累到顿悟”的过程,或许这就是计算机知识的特征:每个概念都建立在一大堆概念之上,而且都是多因素网状关联,需要同时“拥有”才能得到“答案”。 5.2 动手实施
示例程序还是比较“复杂”,因为它需要演示板上所有的功能。以STM3210B‐EVAL为例,它上面有LCD、按钮、JoyStick、M25 Flash等外设,还支持了串口调试工具uC/Probe。 第一步我要的是一个“干净”的模板,只需要驱动一个LED,即一个IO口,因为这几乎是所有系统都会设计的。 通过这个模板,我希望理解uCOS下的程序是如何工作的。 至于调试用的 uC/Probe,相对于这一步所具备的水平,属于“奢侈品”,暂时还无法享用,所以暂不考虑,等日后程序功能多了,编程自如了,再“锦上添花”。 第一步:构建程序目录
首先根据自己的需要构建一个目录。 第 7 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
因为我希望分步实现目标,将每一步都保留,而不是做完后只剩最后一步的内容,这样别人参考就比较容易,不会像uCOS附带的示例程序,内容太多,难以消化。 但不希望每一步的目录中都包含ST和uCOS的库文件,这样一是文件太大,二是如果库文件要升级会很麻烦。 为此,构建了以下目录结构: COMMON目录是基本不用修改的,其中内容来自: ..MicriumSoftwareCPUSTSTM32 STM32LIB ..MicriumSoftwareuC‐CPU uC‐CPU ..MicriumSoftwareuC‐LIB uC‐LIB ..
MicriumSoftwareuCOS‐II uCOS‐II ..
MicriumSoftwareuC‐Probe uC‐Probe 虽然这一步不用 uC/Probe,但日后考虑会使用,故保留。 感到遗憾的是Micrium程序包中所附的ST库是2.0版的,本来打算自己更换为3.0版,但发现有些困难,初学乍练,不敢造次,就放弃了,留待日后升级吧。 学习目录目前只有 StepByStep‐1 一个,分为三个子目录: asp —— 用于存放应用程序,就是实现功能的程序。工程文件在这个目录中。 bsp —— 用于存放相应的硬件驱动程序,用到什么添加什么。 out —— 存放所有编译、链接产生的文件,交流时这个目录内容可以不拷贝。 这样每做一步都建立一个目录,逐步丰富内容。 第 8 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
asp、bsp目录中的文件均以上述“uCOS程序关系图”中所描述的文件为基础。 第二步:构建自己的bsp文件 我参考的是这个目录: ..
MicriumSoftwareEvalBoardsSTSTM3210B‐EVALRVMDKBSP 它包含以下文件: 我不用LCD,所以去掉,bsp文件如下: 注意:除删除了三个与LCD显示相关的文件外,bsp.h和bsp.c 也作了相应修改,主要是删除了不用的外设初始化和驱动程序,只保留了必须的驱动(详见程序清单)。 bsp_int.c 和中断初始化相关,因第一步不涉及中断,故暂不处理。 Bsp_periph.c 初始化各外设的时钟,因未吃透,也暂不处理。 Init.s 是启动代码,程序复位后的入口,因第一步无特殊要求,也没有能力变出花样,不去碰它。 两个SCAT 文件是程序装载时的定位文件,STM32在这上面有不少花样,可以将指定程序加载到指定位置等,未来如果要实现小车远程程序下载或许会用到,此时还一知半解。 第 9 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
按我的理解: STM32_ 文件是为了编译生成FLASH中运行的程序用的,STM32_应该是编译生成RAM中运行的程序用的。刚从51上来,对在RAM中运行还不熟悉,故建立工程时用的是FLASH方式。 这个目录会随着外设的不断起用而丰富起来。 第三步:构建自己的应用程序
因为原来STM3210B‐Eval板就有LED显示功能,而且是4个,我所做的就是删除所有不用的功能,将4个LED驱动改为一个即可。(注意:是删除,不是注释掉) 删除后的app相当“单纯”: 第 10 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
APP目录下有如下文件: 其中app_cfg.h 也很“单纯”: 只有一个任务,确定其优先级和所用栈尺寸即可。 includes.h 里面有许多是系统需要的头文件,还没有吃透,暂不处理。 os_cfg.h 是uCOSII的配置文件,日后需要裁减系统时再琢磨,第一步不去惹它,以免系统罢工。 stm32f10x_conf.h 是STM32的配置文件,不启用的外设就注释掉,此处不用删除,因为恢复时太麻烦。 第一步应用部分只使用了一个IO口:PA3,所以从应用角度只需要打开GPIO、GPIOA,但AFIO似乎系统用了,去掉后系统编译出错,只能保留。 按我的理解,一些基础的功能系统应该需要,如中断、时钟、定时器等,没想到可以将SysTick及所有TIM注释掉,不清楚系统是如何产生定时任务切换的,如果要深入系统,这就是一个值得探讨的点。(具体保留了那些外设详见程序) vectors.s中定义了STM32所有外设的中断向量,似乎没有必要去碰它。 至此,第一步所需要的源文件已经完成,下面要拿出来“遛遛”了。 第 11 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
第四步:在MDK中构建工程 我所使用的是MDK3.5版本。构建过程如下: 1)在Project菜单中选择“New uVision Project”,创建一个新工程,放在app目录下;我所创建的工程文件名是: YM4‐STM32‐2 2)在Project菜单中选择“manage”,为工程设置工程目标名、文件组,并在每个文件组中添加对应的文件: 因为编译产生的文件是在Flash上运行的,所以目标名用“Flash”,我觉得这个纯粹是为了便于记忆、理解。 文件组是参考示例程序及自己的理解确定的。 确定组后,添加相应的文件,包括C、S、asm(汇编)程序,asp、bsp组的文件来自对应的目录。其它都是系统文件,具体如下: STM32‐LIB文件添加自:(注:我是根据STM32f10x‐conf.h确定要添加的文件的) uCOS‐StepbyStepCOMMONSTM32LIBsrc 第 12 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
uC‐CPU 文件添加自: uCOS‐StepbyStepCOMMONuC‐CPUARM‐Cortex‐M3RealView uC‐LIB文件添加自:(注:因第一步未用,故没有添加文件) uCOS‐StepbyStepCOMMONuC‐LIB uCOS‐StepbyStepCOMMONuC‐LIBPortsARM‐Cortex‐M3RealView uCOSII 文件添加自: uCOS‐StepbyStepCOMMONuCOS‐IISource uCOS‐Port文件添加自: uCOS‐StepbyStepCOMMONuCOS‐IIPortsARM‐Cortex‐M3GenericRealView 完成上述步骤后,在IDE的Project Workspace 窗口显示如下: 3)鼠标在工程目标名“Flash”上,点右键菜单,选择“Option for Taget Flash” ,开始配置工程选项。 打开后的主界面如下: 第 13 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
依次选择: Device: ST的STM32F103RB Target:默认值 Output: Listing:同Output一样选择输出文件存放目录,也放在out目录下。 Ur:默认(还不明白有什么用处 ) C/C++:这个选项中有很多暂时没有吃透,第一步必须做的是:首先选择编译的的告警提示,建议用 “All Warning”,因为初学,多注意提示能帮助减少程序中的隐患。 其次就是配置include 目录,将COMMON和StepbyStep目录下所有存在 *.h的目录全部添加进去。 如下所示: 第 14 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
Asm:默认 Linker: Debug:按如下内容配置 第 15 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
Utilities:这一步主要配置STM32的FLASH编程算法,如下: 至此,工程全部建立完毕,可以编译了。 第五步:编译、下载、调试 这部分操作没有什么特别之处,用过Keil51就会,即使不熟悉,参考MDK的手册即可。 JTAG工具用的是市场上最常见的JLink V8。小车控制板较小,选用的是IDC10接口,需要一个转接插头。 编译时建议先单独编译自己写的程序,此处是:asp.c bsp.c 。这样便于出错,因为编译产生的提示信息相对少些。 排除错误后再进行“Build Taget” 。 第 16 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
小车调试方式如下: 很幸运,uCOSII下的第一个程序如愿运行了 ☺ 六、总结 这是我的第一个uCOSII应用程序,虽然简单,但它帮助我初步理解了如何在uCOS下编写程序,uCOS程序大概(也就达到了这个水平)是如何运行的。 有了这个基础,就可以逐步深入,以小车的控制为需求,依次启用STM32上的外设,编写相应的BSP,并根据需要编写相应的应用程序。 通过这一步,自我感觉再看uCOS源程序时容易理解多了,以前看时是被动的接受书中的概念,而这次是先有疑问,再去找答案。 第 17 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
比如说,如果对照圆梦小车二代的Step‐1程序,用延时方式控制LED闪烁,那就无法再处理其它任务,MCU全给延时循环占用了。 为解此惑,我便看了uCOS的延时源程序,理解它是如何实现延时的。我主要看了两个与定时相关的函数: OSTimeDly(INT16U ticks) OSTimeDlyHMSM(INT8U hours, INT8U minutes, INT8U conds, INT16U milli) 因为有明确的需求,所以容易理解多了,同时还发现了一个小“秘密”:用后一个函数不能提高延时的精度,虽然它提供了ms 参数,看似可以精确到ms,可如果你真想用它达到ms 分辨率的延时一定会失望的,因为它是靠调用前一个函数实现的。 由此得出结论: 1)用系统延时函数最高分辨率就是系统的 ticks,通常tick为10ms,太快了系统开销太大,所以用此方法实现 1ms 分辨率的延时不可行,虽说Step1 的tick 是1ms,但后面会改为10ms。 2)后一个函数最大的用途应该是长延时,用前一个函数最长只能 65535 个ticks。 3)如果延时小于 65535 ticks,最好用前一个,可降低开销。 4)因为这个延时是利用任务控制块中的延时计数实现的,所以精度不高,如果要准确延时,比如形成周期,最好还是直接用定时器中断配合消息机制实现。 为理解OSTimeDly,顺带看了时钟节拍函数:OSTimeTick(void),初步了解了任务切换的过程。 此文属于随笔,注重叙述过程和感悟,不想深入探讨系统实现,等小车的控制初具雏形后再考虑是否需要对应写一系列文章,专门探讨每一步所涉及的系统函数是如何工作的。 第 18 页 共 19 页 uCOS 学习随笔 StepbyStep‐1 Project: fira‐mirosot‐robot
读者如果有兴趣可以自己先尝试一下,我觉得Step1应该了解的是: 1)
2)
uCOSII的系统定时是如何产生的?使用的STM32什么硬件资源? 看看用到的几个OS函数源代码,它们的功能是什么?如何实现? 如: BSP_IntDisAll() OSInit() OSTaskCreate() OSTaskCreateExt() OSTaskNameSet() OSStart() 此外还有BSP中的一些函数 3)
Step‐1 到此结束,准备着手根据需求构建任务了。 但愿本文能对那些和我一样曾经蠢蠢欲动多次又无疾而终的uCOS学习者有帮助,大家共同交流、进步! —————————— 2010年10月20日星期三 参考资料: 1、《嵌入式实时操作系统 uC/OS‐II(第二版)》邵贝贝 等译 ISBN7‐81077‐290‐2 2、《基于嵌入式实时操作系统的程序设计技术》周航慈 吴光文著 ISBN978‐7‐81077‐941‐8 3、《Cortex‐M3 + uCOS‐II嵌入式系统开发入门与应用》陈瑶等著 ISBN978‐7‐115‐23105‐5 4、《uC/OS‐II 标准教程》杨宗德 张兵 著 ISBN978‐7‐115‐20442‐4 5、uC/OS‐II 官方网站资料 6、奋斗STM32 MINI 学习板资料 消化任务控制块 TCB 中各个变量的作用,对理解OS函数很有帮助。 第 19 页 共 19 页
本文发布于:2023-12-10 23:10:49,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/zhishi/a/1702221049242268.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:一步步建立 STM32 UCOS 模板.doc
本文 PDF 下载地址:一步步建立 STM32 UCOS 模板.pdf
留言与评论(共有 0 条评论) |