《嵌入式系统开发技术》——课程设计(实习)报告信息工程学院编制任务项目2 按键中断控制串口 (3)1. 目的 (3)2. 内容 (3)3. 要求 (3)任务项目3 PWM控制蜂鸣器以及通过串口控制其频率 (6)1. 目的 (6)2. 内容 (6)3. 要求 (6)任务项目4看门狗定时器编程 (9)1. 目的 (9)2. 内容 (9)3. 要求 (9)任务项目5 u-boot源码详细分析 (12)1. 目的 (12)2. 内容 (12)3. 要求 (12)4. 附录 (12)5.代码注释 (15)心得体会 (18)任务项目2 按键中断控制串口1. 目的(1)熟悉裸机按键中断的发生及通过串口输出字符过程。
2. 内容独立编写程序实现:(1)当按下按键SW7时发生中断,设计中断服务函数使得蜂鸣器鸣响同时串口输出SW7。
(2)当按下按键SW8时发生中断,设计中断服务函数使得蜂鸣器结束鸣响同时串口输出SW8;3. 要求请将实验过程截图黏贴到下面的空白处。
任务项目3 PWM控制蜂鸣器以及通过串口控制其频率1. 目的(1)熟悉裸机下PWM定时器、串口程序的编写。
2. 内容(1)参照课本程序调试运行使得PWM定时器能控制蜂鸣器;(2)加入串口程序使得当在串口输入“A”和“B”时蜂鸣器能以不同的频率鸣响。
提示:可参看教材中断这一章编写程序。
3. 要求请将实验过程截图黏贴到下面的空白处。
任务项目4看门狗定时器编程1. 目的(1)熟悉裸机下看门狗定时器程序的编写、测试及运行。
2. 内容(1)参看课本程序,调试运行,实现通过定时器精确控制蜂鸣器延时1秒钟;(2)控制蜂鸣器鸣响使之模仿简单歌曲《读书郎》。
提示:参看系统时钟和定时器这一章编写程序。
3. 要求请将实验过程截图黏贴到下面的空白处。
任务项目5 u-boot源码详细分析1. 目的(1)熟悉u-boot工程的总体结构。
(2)熟悉u-boot的流程、主要的数据结构、内存分配。
(3)熟悉u-boot的重要细节,主要分析流程中各函数的功能。
2. 内容S5PV210 u-boot源码分析3. 要求请添加u-boot源码注释,查看相关数据手册,添加代码注释,以实验台为基数,每组完成i部分的50行代码。
注释添加示例:Start.S中一段程序:.globl _start_start: b reset // b是跳转指令,即跳转到reset标签处。
接着返回到此处。
ldr pc, _undefined_instruction //设置中断向量表0x0 0x4.....0x8 0xcldr pc, _software_interruptldr pc, _prefetch_abortldr pc, _data_abortldr pc, _not_usedldr pc, _irqldr pc, _fiq4. 附录1. u-boot启动流程1.1 启动阶段分为3个,bl0,bl1,bl2。
下面只是就功能方面对它们做说明,实际设计的时候,也许会对其具体功能做出调整,也就是说,这几个阶段的划分是就功能而言的,不能看得太死。
bl0:出厂的时候就固化在irom中一段代码,主要负责拷贝8kb的bl1到s5pv210的一个96kb大小内部sra m(Internal SRAM)中运行。
值得注意的是s5pv210的Internal SRAM支持的bl1的大小可以达到16kb,容量的扩增是为了适应bootloder变得越来复杂而做的。
虽然如此,但目前我们制作出来的bl1的大小仍然可以保持在8kb以内,同样能满足需求。
bl1:u-boot的前8kb代码(s5pv210也支持16kb大小,原因上一点提过了),除了初始化系统时钟和一些基本的硬件外,主要负责完成代码的搬运工作(我设计成搬运bl1+bl2,而不仅仅是bl2),也就是将完整的u-boot代码(bl1+bl2)从nand flash或者mmcSD等的存储器中读取到内存中,然后跳转到内存中运行u-boot。
bl2:完成全面的硬件初始化和加载OS到内存中,接着运行OS。
上述几个阶段的流程描述在s5pv210_irom_application手册中有详细描述。
见下图1:图11.2 首先把启动部分的代码分为3部分,以start.S为主,另外还有lowlevel_init.S,mem_setup.S,ctr0.S。
其中lowlevel_init.S主要是一部分硬件的初始化,尤其是系统时钟和DRAM 的初始化。
如果u-boot一旦被搬运到内存中运行,那么是必须要跳过时钟和DRAM的初始化的,因为这在搬运之前已经做过了。
并且如果代码在内存中运行的时侯你却去初始化DRAM,那必然导致崩溃!mem_setup.S:DRAM初始化代码和MMU相关代码放在这个文件中。
ctr0.S:u-boot自带的代码文件,存放汇编函数main。
1.3 启动代码相关的几个文件在u-boot中的路径start.S: /arch/arm/cpu/armv7/start.S (需要自己修改)lowlevel_init.S:/board/samsung/zsy210/ lowlevel_init.S (需要自己修改)mem_setup.S: /board/samsung/zsy210/ mem_setup.S (u-boot没有,需要自己添加)ctr0.S: /arch/arm/lib/ctr0.S (u-boot自带,一般不需要修改)2. 启动过程原理必须要明白的一点是,当代码从存储介质(nand flash,SD,norflash,onenand等)中搬运到了DRAM中后随即会跳转到内存中运行u-boot,接着会有一个重定位(relocate_code)的过程,relocate_code子函数在start.S中,而给relocate_code子函数传参数的是crt0.S中的main子函数。
当判断到当前u-boot 在内存的低地址处,那么relocate_code就会工作,把u-boot代码从低地址处再搬运到内存地址的顶端,然后跳转到新的位置去继续运行u-boot。
而搬运的目标地址是在board_init_f()函数(此函数在/arch/arm/lib/board.c中)中计算出来的,见图2。
图2下面,以start.S为主线,画出了其程序流程图,图中同样也表现出启动的整个流程和启动代码文件间的组织关系。
所以后面直接贴出start.S的完整代码,大家结合流程图相信都可以看明白,至于逐句汇编的分析不是本文的重点。
见图3.图35.代码注释relocate_done://搬迁完成1.2.3.bx lr //即跳转到lr中存放的地址处。
4.5._rel_dyn_start_ofs:/* r2 <- rel dyn start ofs *///r2=0x64854(反汇编)6..word __rel_dyn_start -_start/* r2 <- rel dyn start ofs *///r2=0x64854(反汇编)7._rel_dyn_end_ofs:/* r3 <- rel dyn end ofs *///r3=0x6d104(反汇编)8..word __rel_dyn_end - _start9._dynsym_start_ofs:/* r10 <- sym table ofs *///r10=0x6d104(反汇编)10..word __dynsym_start - _start11.ENDPROC(relocate_code)12.13.#endif//预编译14.15.ENTRY(c_runtime_cpu_setup)//进入CPu启动16./*17. * If I-cache is enabled invalidate it18. */19.#ifndef CONFIG_SYS_ICACHE_OFF //结束预编译mcr p15, 0, r0, c7, c5, 0 @ invalidate icache//ARM的协处理命令20.mcr p15, 0, r0, c7, c10, 4 @ DSB//ARM的协处理命令21.mcr p15, 0, r0, c7, c5, 4 @ ISB//ARM的协处理命令22.23.#endif//预编译24./*25. * Move vector table//移动向量表26. */27.#if !defined(CONFIG_TEGRA20)//结束预编译28./* Set vector address in CP15 VBAR register */29.ldr r0, =_start//从内存中读出30.add r0, r0, r9 //三项相加31.mcr p15, 0, r0, c12, c0, 0 @Set VBAR//协处理32.#endif /* !Tegra20 *///结束预编译33.34.bx lr//跳转到lr35.36.ENDPROC(c_runtime_cpu_setup)//cpu开始37.38./*************************************************************************39. *40. * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)//无效启动参数保存41. * __attribute__((weak));42. *43. * Stack pointer is not yet initialized at this moment//堆栈指针尚未初始化44. * Don't save anything to stack even if compiled with -O0//不保存任何堆栈即使编译45. *46.*************************************************************** **********/47.ENTRY(save_boot_params)//48.bx lr @ back to my caller49.ENDPROC(save_boot_params)//保存引导50..weak save_boot_params //51.52./************************************************************心得体会这次实验让我认识到了自己的不足。
还有许多可以改进。
看门狗定时器编程播放儿歌小二郎,对音乐节拍的把控不足,还有对程序延时的理解,使我走了很多弯路,但是也让我学习到了很多新东西。