资源预览内容
第1页 / 共45页
第2页 / 共45页
第3页 / 共45页
第4页 / 共45页
第5页 / 共45页
第6页 / 共45页
第7页 / 共45页
第8页 / 共45页
第9页 / 共45页
第10页 / 共45页
亲,该文档总共45页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
1RTOS编程培训2课程目的 掌握RGOS线程调度的基本原理 熟练应用IPC进行多线程开发 掌握RGOS的中断和定时器管理机制 掌握RGOS内存管理的正确使用方法 学会搭建RGOS的编程环境,掌握基本的嵌入式开发和调试技能3考核方式 笔试(闭卷) 60% 上机 40%编程练习上机调试4课程内容 开发环境与调试方法 系统调度、中断与线程间通信 多线程开发常见问题、定时器与内存管理5学习指导 RGOS的一些基本概念注意理解和区分 理解并掌握各种机制的应用场合 对开发过程中的约束和注意事项要牢记 接口只要在要用的时候会用即可参考资料 Operating System ConceptsAbraham Silberschatz Peter Baer Galvin,Greg Gagne John Wiley thendefine_bool CONFIG_SYS_ASSERT y fi config.in文件的包含关系bool Support redundancy? CONFIG_RDND if “$CONFIG_RDND“ = “y“ ; theninclude kernel/rdnd/config.in fi22第二步:编写配置文件配置项的最终保存方式配置项的最终保存方式Program/Project/conf/.configProgram/Project/conf/.config(配置结果文件)(配置结果文件)以以makefilemakefile中变量的形式中变量的形式保存所有的配置项保存所有的配置项用于指导用于指导makefilemakefile中的编译和链接中的编译和链接Program/Project/conf/autoconf.hProgram/Project/conf/autoconf.h(配置结果头文件)(配置结果头文件)以以C C语言中语言中宏定义的形式宏定义的形式保存所有的配置项保存所有的配置项按模块分解成多个按模块分解成多个.h.h,用于源文件中,用于源文件中23第二步:编写配置文件pMakefile文件的一般格式:O_TARGET := _sub_xxx.o #注意:xxx为当前目录名subdir-y := d1 d2 #我想编译当前目录下的哪些子目 录obj-y := y1.o y2.o #我想编译当前目录下的那些文 件EXTRA_CFLAGS += -Walloverride EXTRA_INCLUDE += -I$(TOPMK)/./include#我还想将哪些目录作为系统头文件目录(可用包含)include $(TOPDIR)/Rules.make #这个必须加24第二步:编写配置文件pMakefile中如何使用配置项如:/driver/makefile中的一部分O_TARGET := _sub_driver.osubdir-y := asyncsubdir-$(CONFIG_I2C) += i2csubdir-$(CONFIG_MTD) += mtdsubdir-$(CONFIG_PCI) += pci# 当.config文件中CONFIG_PCI=y时,实际上就等于:# subdir-y+=pci25第二步:编写配置文件pMakefile中如何使用配置项Ifeq (“$(CONFIG_UART_LL)“, “y“)Ifeq (“$(CONFIG_UART_LL)“, “y“) obj-y += uart_debug.oobj-y += uart_debug.o else else obj-y += uart.oobj-y += uart.o EndifEndif思考:能否使用思考:能否使用obj- $(CONFIG_UART_LL)obj- $(CONFIG_UART_LL)这种方式?这种方式?26第三/四步:配置与编译p命令配置:makes config编译:makesp进行配置操作后生成的文件Program/Project/conf/.config Program/Project/conf/.config(配置结果文件)(配置结果文件)Program/Project/conf/autoconf.h Program/Project/conf/autoconf.h(配置结果头文(配置结果头文 件)件)p进行编译操作后生成的文件xxx.bin_可执行程序xxx.disasm.gz压缩后的反汇编文件其他文件其他文件27示例:如何添加一个新的模块1. 新的模块目录就位2. 编写模块内部的配置菜单config.in3. 编写这个新目录内的Makefile4. 添加这个新模块的加载菜单5. 修改上一级目录的Makefile28示例:如何添加一个新的模块例子:在driver目录下加入AAA设备的驱动模块.(假设该模块代码包括a1.c和a2.c)1. 确定AAA设备驱动模块所在的位置(/driver/aaa/目录下)2. 编写AAA模块的配置菜单(/driver/aaa/config.in):comment AAA Driver config # # AAA driver module config # bool use A1 COFNIG_AAA_A1 bool use A2 COFNIG_AAA_A229示例:如何添加一个新的模块3. 编写aaa模块的makefile文件(/driver/aaa/makefile):O_TARGET := _sub_aaa.osubdir-y :=obj-y :=obj- $(CONFIG_AAA_A1) += a1.o obj- $(CONFIG_AAA_A2) += a2.oinclude $(TOPDIR)/Rules.make30示例:如何添加一个新的模块4. 修改driver模块的配置文件( /driver/config.in ):在/driver/config.in中加入对AAA的配置bool Support AAA CONFIG_AAA# Config AAAif “$CONFIG_AAA“ = “y“ ; theninclude driver/aaa/config.infi5. 修改上一级目录的makefile( /driver/makefile ):在/driver/makefile中加入subdir-$(CONFIG_AAA) += aaa31第五步:载入程序pBoot下更新程序的方法1.按Ctrl + b进入Boot模式2.使用Xmodem更新Boot或Ctrlp Ctrl/Bootloader下载入程序的方法1.Ctrl + c进入Ctrl模式或Bootloader模式2.使用Xmodem或TFTP功能更新Ctrl/Bootloader或Main注意:Boot/Bootloader/Ctrl不得轻易更新,否则会导致设备无法启动。Xmodem/TFTP的具体操作请参见各模式下的帮助信息(使用help命令)32n 开发环境n 开发基本流程n 子系统n 常用调试方法33子系统介绍 为何要使用子系统可卸载性模块的初始化 子系统的类型不可卸载的子系统 - 内存管理模块可卸载的子系统 - 一些协议模块34子系统初始化阶段划分基础类初始化链路层初始化网络层初始化应用层初始化驱动初始化最终阶段基础类 (SUBSYS_CLASS_BASIC): 被后续所有模块依赖的模块并且不依赖于任何其他应用模块 链路层模块(SUBSYS_CLASS_LINKLAYER): 链路层框架、链路层协议(不含驱动) 网络层模块(SUBSYS_CLASS_NETWORKLAYER): 网络层框架和协议。 应用层模块(SUBSYS_CLASS_APPLICATION): 网络层框架和协议。 驱动(SUBSYS_CLASS_DRIVER): 各种驱动,如PCI等 最终阶段(SUBSYS_CLASS_LAST): 从初始化顺序上讲必须位于上述阶段之后的模块 35可卸载子系统的创建1. 编写子系统2. 编写配置文件3. 修改makefile文件36编写子系统1. 明确本模块需要在哪个阶段初始化2. 明确子系统的依赖关系和初始化顺序关系3. 明确本模块的初始化函数37子系统的定义l SUBSYS_DEFINE_00(subsysname,SUBSYS_CLASS_XXX, 1, xxx_init, dependance, sequence); dependance子系统所依赖的其他子系统。若所依赖的子系统不存在,那么该子系统不能被初始化。 sequence子系统初始化之前需要先初始化的子系统列表。列表中的子系统如果不存在,不会影响到该子系统的初始化38子系统的定义例子:SUBSYS_DEFINE_00(a1, SUBSYS_CLASS_DRIVER, 1, a1_init, “pci”, NULL);SUBSYS_DEFINE_00(a2, SUBSYS_CLASS_LINKLAYER, 1, a2_init, NULL, NULL);SUBSYS_DEFINE_00(a3, SUBSYS_CLASS_LAST, 1, a3_init, “a1, a2”, “a1, a2”);39子系统示例:Hello Worldstatic void hello_main(unsigned long argc, void *argv) while (1) printk(“Hello World!n“);sleep(HZ); static void init_helloworld() printk(KERN_INFO “Start hello world task.n“);hello_task = create_task(“hello_world“,hello_main, 0, NULL,HELLO_TASK_STACK, APP_TASK_TS); SUBSYS_DEFINE_00(helloworld, SUBSYS_CLASS_LAST, 1, init_helloworld, NULL, NULL);40n 开发环境n 开发基本流程n 子系统n 常用调试方法41嵌入式开发调试的特点 编译与运行在不同平台交叉编译 缺乏调试软件的支持PC端有gdb之类软件的支持嵌入式系统无法直接单步跟踪运行情况 单步跟踪调试困难调试器数量有限,且使用比较困难通过打印变量值观察分析RGOS上的常用调试方法 打印分析+走读代码最常用、最有效的调试手段 故障诊断命令的辅助debug support模式下的故障诊断命令 show命令 exec命令一键通命令4243代码审查 代码自查与代码评审对照代码审查表 上机调试前的必备工作 指针运算要特别小心 注意成对操作的匹配 不要急着编译运行准备充分了吗?不要做浮躁的人练习 搭建嵌入式开发环境,使PC能够通过串口线与目标设备通讯(串口有字符输入输出) 练习工程能够正确编译通过,并加载到目标设备上运行(可以通过串口或网口加载) 实现一个子系统,能够在目标设备上通过串口打印出“Hello World!”字符串。串口打印的函数为printk 修改子系统初始化的阶段,看看串口打印“Hello World!”的时刻有什么变化45
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号