1 / 32

嵌入式系统设计与实例开发 —— ARM 与  C/OS-Ⅱ 第五讲 嵌入式软件的移植

嵌入式系统设计与实例开发 —— ARM 与  C/OS-Ⅱ 第五讲 嵌入式软件的移植. 第四讲、 嵌入式系统的移植. 移植的概念和目的. 1. 2. 操作系统移植. 3. 软件移植. 4. 5. 一、移植的概念和目的. 移植:程序或应用软件从一个系统平台移动另一个系统平台,其功能、结构、执行结果保持不变。 移植的目的: 1 、硬件平台的升级 2 、实现软件重用 3 、实现软件 / 硬件并行设计 移植的要求: 1 、移植对象具有硬件无关性 2 、移植对象具有系统无关性 3 、移植对象采用标准语言编程.

thane-gay
Download Presentation

嵌入式系统设计与实例开发 —— ARM 与  C/OS-Ⅱ 第五讲 嵌入式软件的移植

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 嵌入式系统设计与实例开发 ——ARM与C/OS-Ⅱ 第五讲 嵌入式软件的移植

  2. 第四讲、嵌入式系统的移植 移植的概念和目的 1 2 操作系统移植 3 软件移植 4 5

  3. 一、移植的概念和目的 • 移植:程序或应用软件从一个系统平台移动另一个系统平台,其功能、结构、执行结果保持不变。 • 移植的目的: 1、硬件平台的升级 2、实现软件重用 3、实现软件/硬件并行设计 • 移植的要求: 1、移植对象具有硬件无关性 2、移植对象具有系统无关性 3、移植对象采用标准语言编程

  4. 二、嵌入式操作系统的移植——μC/OS-II • μC/OS-II的软硬件体系结构 • μC/OS-II的移植需要满足的要求 • μC/OS-II移植的主要工作 • BSP的概念及应用

  5. 2.1 μC/OS-II的软硬件体系结构

  6. 2.2 μC/OS-II的移植需要满足以下要求 (1)处理器的C编译器可以产生可重入代码; (2)可以使用C调用进入和退出Critical Code(临界区代码); (3)处理器必须支持硬件中断,并且需要一个定时中断源; (4)处理器需要能够容纳一定数据的硬件堆栈; (5)处理器需要有能够在CPU寄存器与内存和堆栈交换数据的指令。

  7. 打开/关闭中断 在COS-II中,可以通过: OS_ENTER_CRITICAL () OS_EXIT_CRITICAL() 宏来控制系统关闭或者打开中断。这需要处理器的支持。 在ARM7TDMI的处理器上,可以设置相应的寄存器来关闭或者打开系统的所有中断。

  8. 处理器支持中断并且能产生定时中断 COS-II是通过处理器产生的定时器的中断来实现多任务之间的调度的。ARM7TDMI的处理器上可以产生定时器中断。 本系统工作在60MHz的主频下,定时器的中断的频率为1000Hz。也就是系统的响应时间为1ms。

  9. 处理器支持硬件堆栈 COS-II进行任务调度的时候,会把当前任务的CPU寄存器存放到此任务的堆栈中,然后,再从另一个任务的堆栈中恢复原来的工作寄存器,继续运行另一个任务。所以,寄存器的入栈和出栈是COS-II多任务调度的基础。 ARM7处理器中有专门的指令处理堆栈,可以灵活的使用堆栈。

  10. 2.3 μC/OS-II移植的主要工作 • 处理器和编译器相关代码 • μC/OS-II的BSP的编写

  11. COS-II在S3C44B0X上的移植 • 设置OS_CPU.H中与处理器和编译器相关的代码 • 用C语言编写六个操作系统相关的函数(OS_CPU_C.C) • 用汇编语言编写四个与处理器相关的函数(OS_CPU.ASM)

  12. ·OS_CPU.H中需要设置一个常量来标识堆栈增长方向;·OS_CPU.H中需要声明几个用于开关中断和任务切换的宏;·OS_CPU.H中需要针对具体处理器的字长重新定义一系列数据类型;·OS_CPU_A.ASM需要改写4个汇编语言的函数;·OS_CPU_C.C需要用C语言编写6个简单函数;·OS_CPU.H中需要设置一个常量来标识堆栈增长方向;·OS_CPU.H中需要声明几个用于开关中断和任务切换的宏;·OS_CPU.H中需要针对具体处理器的字长重新定义一系列数据类型;·OS_CPU_A.ASM需要改写4个汇编语言的函数;·OS_CPU_C.C需要用C语言编写6个简单函数;

  13. 设置与处理器和编译器相关的代码 • OS_CPU.H中定义了与编译器相关的数据类型。比如:INT8U、INT8S等。 • 与 ARM处理器相关的代码,使用 OS_ENTER_CRITICAL() 和 OS_EXIT_CRITICAL() 宏开启/关闭中断 • 设施堆栈的增长方向 :堆栈由高地址向低地址增长

  14. 用C语言编写六个操作系统相关的函数 • void *OSTaskStkInit (void (*task)(void *pd),void *pdata, void *ptos, INT16U opt) • void OSTaskCreateHook (OS_TCB *ptcb) • void OSTaskDelHook (OS_TCB *ptcb) • void OSTaskSwHook (void) • void OSTaskStatHook (void) • void OSTimeTickHook (void) 后5个函数为钩子函数,可以不加代码

  15. 用汇编语言编写四个与处理器相关的函数 • OSStartHighRdy() • OSCtxSw() • OSIntCtxSw() • OSTickISR()

  16. 实现方法 • 在每个硬件时钟到来后,μC/OS-II会在中断服务例程中调用OSIntCtxSw()进行任务调度;另外,当某个任务因等待资源而被挂起时,没有必要等到自己的时间片全都用完,可以自己主动放弃CPU,这可以通过调用一个任务级的任务调度函数OSCtxSw()来实现。 • 其中相对复杂的是OSIntCtxSw()。由于OSTickISR()调用了OSIntExit(),OSIntExit()又再次调用了OSIntCtxSw(),如果进行任务切换,那么两次调用都不会返回,而不同的C编译器、不同的编译选项处理C调用时对堆栈的使用也不尽相同。因此OSIntCtxSw()是编译器相关的。

  17. μC/OS-II任务堆栈初始化 • μC/OS-II中每个任务都有自己的任务堆栈,在任务创建初期由OSTaskStkInit()初始化。初始化堆栈的目的就是模拟一次中断。任务堆栈中保存了任务代码的起始地址和一些CPU寄存器(初值是无关紧要的),这样一旦条件满足,就可以执行该任务了。

  18. 2.4 μC/OS-II BSP编写 BSP(板级支持包)是介于底层硬件和操作系统之间的软件层次,它完成系统上电后最初的硬件和软件初始化,并对底层硬件进行封装,使得操作系统不再面对具体的操作。 BSP的特点: • 硬件相关性:因为嵌入式实时系统的硬件环境具有应用相关性,所以,作为高层软件与硬件之间的接口,BSP必须为操作系统提供操作和控制具体硬件的方法。 • 操作系统相关性:不同的操作系统具有各自的软件层次结构,因此,不同的操作系统具有特定的硬件接口形式。

  19. BSP的功能 • 操作系统初始化 A、片级初始化 B、板级初始化 C、系统级初始化 • 硬件相关的设备驱动程序

  20. 嵌入式系统初始化过程及BSP功能

  21. 系统调用通用设备驱动程序与BSP的关系

  22. 设计BSP的方法 一、以典型的BSP做为参考 二、参照操作系统或芯片厂商提供的BSP模板

  23. μC/OS-IIBSP for ARM • μC/OS-II编写一个简单的BSP。它首先设置CPU内部寄存器和系统堆栈,并初始化堆栈指针,建立程序的运行和调用环境; • 然后可以方便地使用C语言设置ARM片选地址(CS0~CS7)、GPIO以及SDRAM控制器,初始化串口(UART0)作为默认打印口,并向操作系统提供一些硬件相关例程和函数如dprintf(),以方便调试; • 在CPU、板级和程序自身初始化完成后,就可以把CPU的控制权交给操作系统了

  24. 二、向嵌入式平台移植软件   大部分嵌入式开发人员选用的软件开发模式是先在PC机上编写软件,再进行软件的移植工作。在PC机上编写软件时,要注意软件的可移植性。 1、选用具有较高移植性的编程语言(如C语言) 2、尽量少调用操作系统函数 3、注意屏蔽不同硬件平台带来的字节顺序、字节对齐等问题。

  25. 字节顺序   字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序,通常有小端、大端两种字节顺序。小端字节序指低字节数据存放在内存低地址处,高字节数据存放在内存高地址处;大端字节序是高字节数据存放在低地址处,低字节数据存放在高地址处。基于X86平台的PC机是小端字节序的,而有的嵌入式平台则是大端字节序的。因而对int、uint16、uint32等多于1字节类型的数据,在这些嵌入式平台上应该变换其存储顺序。 通常我们认为,在空中传输的字节的顺序即网络字节序为标准顺序,考虑到与协议的一致以及与同类其它平台产品的互通,在程序中发数据包时,将主机字节序转换为网络字节序,收数据包处将网络字节序转换为主机字节序。

  26. 字节对齐 •   有的嵌入式处理器的寻址方式决定了在内存中占2字节的int16、uint16等类型数据只能存放在偶数内存地址处,占4字节的int32 、uint32 等类型数据只能存放在4的整数倍的内存地址处;占8字节的类型数据只能存放在8的整数倍的内存地址处;而在内存中只占1字节的类型数据可以存放在任意地址处。由于这些限制,在这些平台上编程时有很大的不同。首先,结构体成员之间会有空洞,比如这样一个结构:typedef struct test{char a;uint16 b;}TEST  结构TEST在单字节对齐的平台上占内存三个字节,而在以上所述的嵌入式平台上有可能占三个或四个字节,视成员a的存储地址而定。当a存储地址为偶数时,该结构占四个字节,在a与b之间存在一个字节的空洞。对于通信双方都是对结构成员操作的,这种情况不会出错,但如果有一方是逐字节读取内容的(通信协议大都如此),就会错误地读到其它字节的内容。其次,若对内存中数据以强制类型转换的方式读取,字节对齐的不同会引起数据读取的错误。因为假如指针指在基数内存地址处,我们想取得占内存两个字节的数据存放在uint16型的变量中,强制类型转换的结果是取得了该指针所指地址与前一地址处的数据,并没有按照我们的愿望取该指针所指地址与后一地址处的数据,这样就导致了数据读取的错误。

  27. 位段   由于位段的空间分配方向因硬件平台的不同而不同,对X86平台,位段是从右向左分配的;而一些嵌入式平台,位段是从左向右分配的。分配顺序的不同导致了数据存取的错误。解决这一问题的一种方法是采用条件编译的方式,针对不同的平台定义顺序不同的位段;也可以在前面所述的两个函数中加上对位段的处理。

  28. 代码优化的问题 •   嵌入式系统对应用软件的质量要求更高,因而在嵌入式开发中尤其须注意对代码进行优化,尽可能地提高代码的效率,减少代码的大小。虽然现代C和C++编译器都提供了一定程度的代码优化,但大部分由编译器执行的优化技术仅涉及执行速度和代码大小的平衡,不可能使程序既快又小,因而必须在编写嵌入式软件时采取必要的措施。

  29. (1)提高代码的效率   ①switch-case 语句。在程序中经常会使用switch-case语句,每一个由机器语言实现的测试和跳转仅仅是为了决定下一步要做什么,就浪费了处理器时间。为了提高速度,可以把具体的情况按照它们发生的相对频率排序。即把最可能发生的情况放在第一,最不可能发生的情况放在最后,这样会减少平均的代码执行时间。  ②全局变量。使用全局变量比向函数传递参数更加有效率,这样做去除了函数调用前参数入栈和函数完成后参数出栈的需要。当然,使用全局变量会对程序有一些负作用。

  30. (2)减小代码的大小   嵌入式系统编程应避免使用标准库例程,因为很多大的库例程设法处理所有可能的情况,所以占用了庞大的内存空间,因而应尽可能地减少使用标准库例程。

  31. (3)避免内存泄漏   用户内存空间(堆)为RAM中全局数据和任务堆栈空间都分配后的剩余空间,为了使程序能有足够的内存运行,必须在申请的内存不用后及时地将其释放,以确保再次申请时能有空间。如果程序中存在内存泄漏(即申请内存后没有及时释放)的情况,程序最终会因为没有足够的内存空间而无法运行。

  32. 谢 谢 各 位

More Related