S698-T处理器的RTEMS移植和应用程序开发

来源:本站
导读:目前正在解读《S698-T处理器的RTEMS移植和应用程序开发》的相关信息,《S698-T处理器的RTEMS移植和应用程序开发》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《S698-T处理器的RTEMS移植和应用程序开发》的详细说明。
简介:一个简单的星载计算机模型由一个模拟真实卫星的嵌入式系统和系统运行所必需的数据集合组成,该数据集合由PC机上运行的程序生成,模拟真实卫星的运行环境。

引言

建立一个简单的星载计算机模型,可以很方便地对某些技术和设备进行验证,降低正式项目的研究成本。模型的各类参数应当与实际的星载计算机一致,因此对构建模型的处理器与相应的操作系统都提出了较高的技术要求。同时,在保证项目质量的前提下控制研究成本,最可靠的办法是采用在航天领域已经成功应用的开源产品。

SPARC是一种开源的精简指令集处理器架构,其突出特点是具有可扩展性。ERC32是欧洲航天局为了打破美国对星载微处理器的垄断地位而开发的一款基于SPARC V7架构的面向空间应用的微处理器,后续基于SPARC V8的处理器也成功应用于航天工程。事实证明,SPARC架构处理器正在航天领域发挥越来越大的作用。RTEMS是一款开源嵌入式实时操作系统,最初由美国国防部开发并应用于导弹控制系统,后来转为开源,由OAR公司进行维护。

本文搭建的星载计算机模型,至少需要一个模拟真实卫星软硬件环境的嵌入式系统和一个系统运行所必需的数据集合。在本文中,嵌入式系统是在SPARC V8架构处理器S698T 基础上移植RTEMS完成的,而数据集合由PC机上运行的程序生成,二者通过串口进行数据通信。

1SPARC和RTEMS简要分析

1.1SPARC架构处理器

SPARC架构处理器与其他RISC架构处理器最大的不同是其拥有“寄存器窗口”结构,一次可对一个大的寄存器组进行操作。

在SPARC架构处理器中,任一时刻一条指令只能使用32个32位通用目的寄存器[]。其中,有8个global寄存器和24个寄存器窗口中的寄存器。上述24个寄存器被平分为3组,分别是in、local和out寄存器。同时,本寄存器窗口的in和out寄存器分配给相邻的两个寄存器窗口作为它们的out和in寄存器,从而使所有的寄存器窗口以循环圈的方式连接起来。进程在不同的窗口间移动,在发生过程调用时,只需切换寄存器窗口,而前后两个寄存器窗口的out和in寄存器组实际上是同组寄存器,这样,在过程调用的过程中参数无需在寄存器中移动。这种重叠寄存器窗口的设计,使得SPARC架构处理器在内存load/store指令的使用次数上,相比于其它RISC架构处理器有着明显的下降,对大型应用程序或需要对大量并发数据进行处理时,这种现象尤为明显。

1.2RTEMS实时操作系统

RTEMS是一种基于平面式内存管理的层次型单体内核,应用程序与RTEMS内核构成一个基于函数调用形式的整体功能单元,二者共享一个CPU特权态,在同一个地址空间下协同完成特定的功能。应用程序和RTEMS内核相互之间可以直接访问,这样做的好处是使需要访问的数据和代码都在内存中,从而保证了内存访问的确定性和实时性,还可以避免额外的内存管理和地址切换的开销。不过,RTEMS没有采用虚拟内存管理,也没有使用分段保护机制,只能够使用有限的物理地址空间,同时在安全性和可靠性方面有所削弱,这需要靠程序员来保证应用程序的正确性和稳定性,以避免因应用程序出错而导致系统崩溃的可能性。但由于嵌入式应用程序一般都是经过完整的测试再发布的,因此上述缺点在实际应用中并不明显。

2星载计算机模型的实现

2.1主要步骤

本文的目标是建立一个简单的星载计算机模型,使之能够对相关技术进行验证。最理想的情况是,在模型操作系统中运行的应用程序应当是实际星务软件在该系统下的移植版本,但为了能够尽早对星载计算机模型进行测试,以便及时发现可能存在的问题,本文将不会涉及星务软件的移植工作。操作系统中运行的应用程序应尽可能简化,但必须能够在S698T处理器上完成一定量的数据处理工作,并实现与PC机间的数据通信功能,模拟的是星载计算机的数据处理流程和与地面控制站的数据通信过程。

首先, RTEMS嵌入式操作系统到S698T处理器的移植,这部分工作的主要内容是RTEMS开发环境的建立和BSP的开发。其次,RTEMS嵌入式操作系统中应用程序的建立,实现串口控制以及与PC机间的数据通信功能。

2.2RTEMS操作系统的移植

2.2.1建立交叉开发环境

开发环境采用宿主机/目标机模式,宿主机为x86架构PC机,运行Fedora 19,目标机为SPARC V8架构的S698T处理器,运行RTEMS。宿主机和目标机通过串口与DSU连接,串口负责数据通信,DSU负责在PC端对S698T处理器进行在线调试。

在Fedora系统中建立交叉开发环境时,安装的交叉开发工具采用添加了RTEMS补丁的GNU工具链(GCC、GDB、binary utilties、newlib等),这些工具可通过在RTEMS官网的ftp服务器上下载对应的RPM包直接安装,比使用源码包编译安装更加方便,且能够避免后者在安装过程中可能遇到的大部分问题。

在安装完交叉开发工具后,需要为系统指定开发工具的安装路径,即设置环境变量:

export PATH=/opt/rtems4.10/bin:$PATH

其中,/opt/rtems4.10/bin是使用RPM包安装交叉编译工具时默认的安装路径。同时需要注意,Fedora采用bash作为shell,如果只在命令终端执行上述命令,则会发现环境变量将还原至初始状态,需要重新设置。该问题最好的解决办法是,将编译工具的路径写到~/.bashrc中:

echo "export PATH="/opt/rtems4.10/bin:"$PATH">>~/.bashrc

重新登录后,环境变量保持改变后的状态。

2.2.2BSP的开发与测试

第1步,选择BSP模板,RTEMS源码提供了市场上流通的大多数架构处理器的BSP模板,从中选择与S698T架构最相似的leon2 BSP作为开发基础,做进一步修改。

第2步,修改BSP配置文件leon2.cfg中相关的结构体系定义。

第3步,修改BSP目录下的所有Makefile.am文件,并重新生成Makefile.in文件。

第4步,修改启动代码,包括建立TRAP表、基本的CPU初始化、设置中断堆栈等。

第5步,RTEMS系统配置,如设置RTEMS配置表、系统初始化任务表、用户初始化任务表等,同时还需要提供板上外设的驱动程序。

第6步,测试和调试,生成可执行映像并下载到S698T处理器上运行,测试BSP的正确性。

2.3BSP的开发

在上述BSP开发相关的步骤中,第3步修改启动代码最为重要。RTEMS BSP的启动代码主要包含在start.s、bootcard.c和bspstart.c等文件中。其中,start.s是系统上电后执行的第一段程序,包含了用于安装trap表和硬件初始化的代码,之后跳转到bootcard.c执行进一步的系统初始化。

2.3.1trap表安装

leon2 BSP中的trap表结构简单,主要作用是对各类trap处理函数入口地址进行统一管理,其格式一般为TRAP( trap_type, SYM(trap_handler)),作用是当处理器发生具体的trap时,系统根据trap_type调用对应的理函数SYM(trap_handler)。

默认的trap表简要如下:

PUBLIC(trap_table)

SYM(trap_table):

RTRAP( 0, SYM(hard_reset) ); ! 00复位

BAD_TRAP; ! 01取指令异常

BAD_TRAP; ! 02企图执行UNIMP或其他未实现的指令

BAD_TRAP; ! 03用户模式下企图执行特权指令

BAD_TRAP; ! 04FPU不存在或关闭时,企图执行浮点处理指令

TRAP(5, SYM(window_overflow_trap_handler) );! 05窗口上溢

TRAP(6,SYM(window_underflow_trap_handler) );! 06窗口下溢

其中BAD_TRAP在start.s文件开头定义,与硬件复位的trap处理函数一致。第0x00~0x7F为硬件trap,其中,第0x7E号trap定义为系统时钟频率,默认为10 MHz;第0x80~0xFF定义为软件trap,可通过ta指令使用。

当掌握trap表中trap及对应处理函数的映射关系后,可以尝试在start.s中对某些BAD_TRAP类的trap的处理函数做出具体的定义:首先在start.s文件开头声明一个trap处理函数,然后在trap表中完成指定处理函数和指定trap的映射关系,最后在strat.s文件末尾前定义具体的处理函数代码,上述代码全部由汇编语句完成。通过这种方式,就可以清楚直观地认识到strat.s中trap表的工作方式,但并不推荐在实际工作中使用这种方法定义自己的trap处理函数。

一般定义自己的trap处理函数是在RTEMS应用程序中完成的。S698T处理器包了32类trap,其中包括S698T处理器的15个一级中断(0x11~0x1F号trap)和32个二级中断。二级中断的输出连在了一级中断的10号中断(0x1A号trap)上,trap_type即所需中断向量号,例如,在安装“系统默认uart0中断”的处理函数时,主要使用的指令如下所示:

rtems_interrupt_catch(uart0_interrupt_handler,0x13,&old_isr_entry);

//捕捉中断向量号为0x13的中断,即uart0中断,将其与一个具体的中断处理函数联系起来

rtems_isr uart0_interrupt_handler(rtems_vector_number vector)//安装具体的中断处理函数

在进入中断处理函数时,首先要关掉中断,在执行完中断处理代码后再打开中断,然后才能退出中断处理函数,返回程序中断点继续运行。

2.3.2系统硬件初始化

在系统上电完成trap表的安装后,开始执行硬件的复位初始化代码,主要完成以下功能:

① 初始化陷阱基址寄存器tbr,将trap表的安装地址存入tbr寄存器中,这也是系统的启动地址,在S698T处理中是0x 4000 0000;

② 初始化窗口无效屏蔽寄存器wim;

③ 使能trap;

④ 设置系统堆栈,根据现有的sp设置fp;

⑤ 复制.data段和清空.bss段;

⑥ 跳转到bootcard.c,完成目标板特定的系统配置和RTEMS的系统初始化。

需要注意的是,默认的硬件初始化代码中没有对psr寄存器和sp寄存器进行初始化,也没有对内存配置寄存器进行初始化,更重要的是,没有对S698T内8个窗口的寄存器进行初始化,可能会造成不必要的异常。因此,在S698T的初始化代码中,必须要对8个窗口的寄存器清零。

对窗口寄存器清零略——编者注。

2.3.3RTEMS的系统初始化

在执行完start.s中的启动代码后,将跳转到bootcard.c,完成RTEMS的基本配置,如设置RTEMS配置表、CPU依赖信息表的相关入口等[3]。bootcard.c会根据目标机环境重新配置RTEMS,为系统初始化任务建立标准C支持环境。最后,开启多任务调度,运行应用程序中配置的第一个任务。

2.4BSP的测试

RTEMS内核与应用程序构成了一个基于函数调用形式的整体功能单元,其最直接的表现形式是RTEMS内核与应用程序代码共同编译生成一个可执行文件,当二者能够正常编译可执行文件,且该文件下载到S698T处理器上后能够正常运行时,证明了BSP的有效性,进而可以进行下一步工作。测试使用RTEMS自带用例hello_world_c,使用默认配置时,生成的可执行文件为hello.exe。

值得注意的是,在编译应用程序时使用标准的Makefile文件,最后编译生成的可执行文件目录下将会有记录整个链接过程的.num文件,该文件记录了hello.exe中所有符号及其在内存中的加载地址。在这里,符号指的是程序中定义过的函数、全局变量和静态变量。

在应用程序的开发过程中,可直接在测试用例Makefile文件基础上进行改造,以减少工作量。

3应用程序开发

在完成BSP的测试后,就要实现S698T处理器与PC机间的数据通信和处理功能,需要在 PC/Windows端和S698T/RTEMS端均开发一个串口控制程序。

3.1PC/Windows端串口控制程序

使用VS2008的MSCOMM控件,在MFC程序中可以很方便地对串口进行控制[4]。而在开发MFC程序时,应当特别注意两个问题:多字节数据的串口连续发送以及不同硬件平台编址方式的差异。

3.1.1多字节数据的串口连续发送

S698T处理器自带两个通用异步串口,其接收和发送缓存均为一个字节,即串口一次只能处理一个字节的数据,而在MFC应用程序中通过串口发送的数据包括整型、长整型、浮点型和字符型,在内存中分别占4、4、4和1个字节。因而必须解决串口中多字节数据连续收发的问题,为此,需要定义一个共同体:

union data

{

int idata; //整型

int ldata; //长整型

float fdata; //浮点型

char scdata; //字符型

char cdata[4]; //字符数组

}temp_data;

共同体所有成员共占一段存储单元,例如上面的定义是把一个整型成员、一个长整型成员、一个浮点型成员、一个字符型成员和一个字符数组成员安排在同一个地址开始的内存单元中[5],从而可用其中的字符数组成员来统一表示其他不同类型的成员数据。

在数据通信时,MFC应用程序给不同类型的数据分配对应的标志位,通过共同体的字符数组成员将所有带标志位的数据组合成一个更大的字符数组,再通过串口依次发送给S698T处理器。S698T/RTEMS端应用程序接收到数据后,将根据事先约定的标志位对数据进行分类处理,再发送回PC/Windows端。

值得注意的是,在MFC应用程序中,当通过串口发送完数据后,应该等待一定时间,这是因为S698T/RTEMS端应用程序通过串口接收数据、经过处理再发送回PC端的整个过程有一定的时间消耗。在没有精确测量S698T/RTEMS端应用程序收发处理数据的整个流程所消耗时间的情况下,MFC应用程序“睡眠”100 ms能够满足需求,但应该还可以继续缩减。当“睡眠”时间结束后,MFC应用程序才开始执行串口数据的接收代码。

3.1.2不同硬件平台编址方式的差异

在通过串口进行数据收发时,还应当注意不同硬件平台上字节顺序方式的差异:SPARC V8为大端字节顺序,而x86为小端字节顺序,同样一个多字节数据,例如浮点数,在两种平台的内存中其字节存放顺序是相反的。这一差异并不会导致应用程序在两种硬件平台间进行数据通信时发生显式错误,但显然在进行数据处理时会生成错误的数据源。因此,在数据处理时,需要根据自身平台的字节顺序方式对接收到的多字节数据进行不同形式的处理。

3.2S698T/RTEMS端串口控制程序

在RTEMS应用程序中可以直接对串口进行控制,方式如下:

#define UART0_DATA *(volatile unsigned int *)(0x80000070)

其中,0x 8000 0070为串口0的数据接收(只读)/发送(只写)寄存器地址,从而在应用程序中可以通过UART0_DATA的不同处理实现对串口的控制。在RTEMS操作系统中对外设的控制均采用相同的处理方式。

RTEMS系统中应用程序主要包括3部分:

① 用户初始化任务Init(),负责串口初始化,创建并启动两个用户任务task1、task2,创建方式略——编者注。

在最后,用户初始化任务Init()负责把自身删除,将CPU控制权转移给任务就绪队列中的第一个任务。

② task1和task2的实现代码,task1通过串口0接收数据并按照SPARC硬件平台上对应的字节顺序分类存放,task2通过串口1逆序发送接收到的数据,task1和task2通过共同体全局变量进行数据通信。特别地,在task1中需要知道什么时候串口0有数据到达,可以检查串口状态寄存器([31:0],共32位)的第[0]位DR,其默认值为0,而当串口接收到新数据时,该位将被写入1,而没有接收到新数据时将保持默认值不变。具体的实现语句如下:

while(1)

{

while(!(UART0_STATUS &0x1));

……//具体的串口数据接收代码

}

每次循环开始时都会判断DR位的状态,当DR位为0,即串口还没有接收到新的数据时,循环内的while()语句构成一个无条件循环,外在表现就是系统持续等待串口输入的状态,而当串口接收到新数据时,DR位置位为1,从而死循环被打破,开始执行接下来具体的串口数据接收代码。接收到的数据依次存放在一个实现定义的字符数组内,以方便数据接收完成后进行处理。

③ 系统配置与裁减,RTEMS系统必须针对特定应用进行配置[6],配置参数包含在一些系统初始化过程中使用到的数据结构中,但RTEMS也提供了一套宏指令,可在应用程序中完成系统的快速配置,如设置RTEMS相关全局变量和常量、RTEMS配置表、API配置表、系统初始化任务表等,还可以提供板上外设的驱动程序。confdefs.h包含了操作系统的配置模板,是实现上述系统配置功能的关键。RTEMS系统配置与裁减可通过预编译的方式来实现[7],一般结构略——编者注。

此时,RTEMS系统配置与裁剪同步完成。而RTEMS系统的初步裁减是在完成BSP开发后进行系统编译配置configure参数时实现的:configure参数的数个disable与enable组合可禁用或许可某些系统功能,从而实现系统的初步裁减。

结语

本文初步实现了搭建一个简单的星载计算机模型的目标,较为详细地论述了模型实现步骤和应该注意的问题,对基于SPARC芯片的RTEMS移植和应用程序开发有了较深刻的认识,相关经验具有一定的借鉴意义。同时,该模型还可继续优化:BSP的开发目前只实现了最基本的功能,还可继续丰富;应用程序应针对数据的循环收发进行改进,将模拟星载计算机控制律输出—卫星状态更新—数据采集的过程,形成一个闭环;实现随机中断、模拟地面数据注入等过程;进一步优化应用程序的时间开销。

提醒:《S698-T处理器的RTEMS移植和应用程序开发》最后刷新时间 2024-03-14 01:01:43,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《S698-T处理器的RTEMS移植和应用程序开发》该内容的真实性请自行鉴别。