在“ts_hdr.asm i i汇编文件中可对默认堆区进行操作,它的主要功能是为默认堆区规定ID号0,以便有新的堆区存在时方便使用。
ts_hdr.asm对默认堆栈进行编号的代码:
· var=1df_defheap_base;
· var=1df_defheap_size;
· var=0;
对链接描述文件和汇编文件进行修改时,只需要在链接描述文件中对新的堆区进行描述并在汇编文件中对其进行编号即可。代码如下:
对新的堆栈区进行描述的代码可开辟于外部存储器之中(SDRAM)。并在新的堆栈中将其编号为1。按照以上步骤将文件修改完毕之后,用户就可以在外部存储区中动态地使用内存了。编译器还为动态内存的开辟提供了一系列的库函数。其具体程序还在内部存储器中的默认堆区动态开辟了大小为50的内存[6(1)],并在外部存储区中动态开辟了大小为256的内存[6(2)]。其程序如下:
int*x,*y;
x=heap_malloc (0,50); (1)
y=heap_malloc (1,256); (2)
5.2 内存覆盖
通过TS101可将数量极大的程序代码放入外部存储器中。每次通过DMA传输方式读入少量的程序代码到内存来执行,这样既扩展了内存空间。又比将全部代码放入外部存储器节省时间,这种方式称为内存覆盖(overlay)。内存覆盖是一种多对一的内存映射技术,它可将多段代码存储在外部存储器划定的不同位置,但也可以在内存中的同一位置运行。代码在外部存储器的存储区称为“live”区,在内存中的运行区称为“run”区。
图2所示是overlay的使用结构图。由图可见,在外部存储器中,overlay1和overlay2可在内存中的同一区域中运行,而overlay3和overlay4也可以在内存的同一区域中运行。当主函数调用FUNC_B时,overlay2将被换入内存中运行,而当主函数调用FUNC_A 时,再用overlay1置换over-lay2,overlay3和overlay4的使用与overlay1和over-lay2相同。代码在内存与外存之间的置换主要通过DMA传输来实现。
内存覆盖管理器是用户编写的用来将函数或数据载入内存的子程序,它们与链接器提供的PLIT{}指令配合使用可完成内存覆盖操作。内存覆盖管理器除了负责由外部存储器向内存的载入操作外,还应当负责建立堆栈保存寄存器的值,检查需要调用的函数是否已经在内存之中,以及利用DMA操作在其它函数执行时运行内存覆盖载入。
通过链接描述文件可对内存覆盖进行辅助操作。此操作需定义OVLY_one和OVLY_two两块overlay代码,其中 OVLY_one包含函数FUNC_A.doj,而OVLY_two包含FUNC_B.doj和FUNC_C.doj,它们共同在MOCode的同一内存区域运行。在链接描述文件中对 overlay进行操作的程序代码如下:
在链接描述文件中,还可以通过定义PLIT{}指令来协助内存覆盖操作的完成。当主函数调用一个内存覆盖区的函数时,链接器将重新引导函数调用并进行操作。例如当主函数调用了内存覆盖函数FUNC_A时,链接器会将其自动转化为调用.plt_FUNC_A操作。此操作在函数执行之前先进行PLIT操作,并跳转到overlay管理器中执行,然后再执行函数A。下面是对PLIT进行操作的定义代码:
5.3 内存扩展的实现
操作系统提供了OS_Process_Sched()函数来完成这一操作,该函数中的进程切换函数顺序代码如下:
(1) 将处于在内存中的进程的寄存器值压入堆栈;
(2) 将处于内存中的进程的全部存储区内容由DMA方式放入外存:
(3) 调用在外存中的进程的寄存器出栈函数;
(4) 跳转到新的进程运行。
在进程调度中,一般首先将所有寄存器值压入当前进程堆栈中进行保存[顺序代码(1)],然后将内存进程存储区中的所有内容放入外部存储器中保存,以便当该进程重新进入内存运行时能够完全恢复原有运行环境[顺序代码(2)]。这里的所有内容是指与当前进程有关的数据,包括进程的堆栈、进程的全局变量、进程动态申请的内存块等等。调用外部存储器中的进程寄存器出栈函数[顺序代码(3)] 主要是利用前面所述的内存覆盖技术来进行的,该寄存器的出栈函数一般放在外部存储器中,操作时可通过调用它使链接器跳转到内存覆盖管理器来完成外部存储器进程向内存的加载。但在这里要对内存覆盖管理器进行修改,并添加外部存储器中进程的全部数据的载入函数,然后,程序才能跳转到新的进程中开始运行[顺序代码(4)]。
6 结束语
本文在对嵌入式实时操作系统进行研究的基础上,完成了基于TS101DSP芯片的嵌入式实时操作系统的设计。所设计的系统体系结构主要参考的是开放源代码的实时操作系统uC/OS_II,并在此基础上,根据芯片本身的特点和实际应用的需要进行了创新和重设计,这主要体现在以下三方面:
(1) 结合TS101芯片的特点,实现了中断处理部分的设计;
(2) 放弃了一般操作系统对内存采取每一任务分配一块内存的方法,而是采用对内存进行分块管理,并采取所有任务公用同一块内存。对同一内存统一管理的方式;
(3) 根据实际系统需要研究,并实现了内存覆盖技术,扩展了系统的存储空间。
当然,任何嵌入式操作系统的设计都有一个简单到详细的过程,需要逐步完善。本文只是完成了TS101嵌入式实时操作系统基本功能的实现。相信经过长期的实际模拟运行,定能建立起功能更加完善、结构更加稳固可靠的嵌入式实时操作系统。