引言
目前,大多数嵌入式系统编程是针对单用户程序,即芯片中只有一个程序。有些情况下,用户希望在芯片中驻留多个用户程序,并能方便更新和选择运行,这就提出了多用户在线编程的需求。随着制造工艺的进步,芯片由8位发展到16位、32位,集成的Flash和RAM也越来越大。这给多用户在线编程提供了基础,而集成的Flash模块给在线编程提供了可能[1]。芯片的发展及资源变化如表1所列。
表1芯片发展及资源变化
嵌入式系统中的多用户在线编程是指,在芯片中驻留一个监控程序,负责下载PC机编译后的用户程序到指定的Flash区域,以及根据用户的选择来运行指定的用户程序。多用户在线编程与单用户在线编程的区别是,多用户程序共享系统资源,极大地提高了资源的利用率,但某一时刻只有监控程序或一个用户程序运行。
本文以飞思卡尔公司推出的内部集成USB2.0模块的32位微控制器MCF52223为例,在分析监控程序、中断向量重定位、全局变量访问等关键技术的基础上,设计并实现了用于机器人开发平台的多用户在线编程系统。
1监控程序设计
监控程序类似于操作系统的内核,是多用户在线编程的核心技术。复位后首先启动监控程序,主要负责通过USB接口下载PC机的多用户程序。监控程序涉及的主要模块包括:USB通信模块、Flash擦除与写入模块、用户程序选择运行模块、中断模块。通过USB模块和Flash擦除与写入模块下载多个用户程序,由用户程序选择运行模块选择某个用户程序运行,从而实现多用户在线编程。
1.1USB通信模块
MCF52223集成了USB 2.0模块[3],可方便、高效地与PC机通信,下载多用户程序。检验正确后,将接收到的用户程序交给Flash擦除与写入模块处理。数据包协议格式如下(数据长度小于512字节):
1.2Flash擦除与写入模块
Flash擦除与写入模块负责将用户程序写入用户区所在的Flash中,从而实现多用户程序的下载。MCF52223拥有256 KB的Flash,分为32个扇区,每个扇区分为4页,每页为2 048字节[4]。擦除的最小单位为一页,因此在设计多用户在线编程系统时,给每个用户分配的空间以页为单位[3]。系统预留6个大小为32 KB的用户区,即最多6个用户在线编程。
1.3监控程序执行流程
监控程序是多用户在线编程的核心,是芯片首先执行的代码。其主要功能是初始化USB通信模块和Flash擦除与写入模块,并通过USB下载用户程序,如图1所示。
图1监控程序执行流程
在全局变量初始化中声明unsigned char UserFlag=0,声明指针unsigned short*Time=(unsigned short *)0x20000400。UserFlag用于保存选择的用户程序。指针Time所指向的区域用于保存定时器中断次数,使得用户区和监控程序能共享全局变量。
2中断向量重定位技术
单用户在线编程系统中每个中断只有一个中断服务程序,中断产生后直接跳转到该中断服务程序中运行,实现起来比较简单[2]。而对于多用户在线编程系统,每个用户程序都可以添加自己的中断服务程序,即对于一个中断号会有多个不同用户的中断服务程序,由原来一对一的关系转变为一对多的关系。中断向量重定位技术就是用来解决这个难题的。
当选择某个用户程序运行时,全局变量UserFlag记录了用户号,产生中断后会从监控程序的中断向量表中查找中断服务程序的入口地址。但由于是多用户编程,还需根据当前用户程序标志UserFlag查找中断向量重定位表,得到当前用户程序的相应中断程序入口地址,并跳转到当前用户相应中断程序执行(即由传统的直接跳转转变成多级间接跳转),如表2所列。中断执行流程如图2所示。
表2中断向量重定位表
图2中断执行流程
每个用户程序中有一张中断向量重定位表,用于跳转到用户编写的中断服务子程序。每个用户区的中断服务程序的函数名已经固定好,用于指定入口地址。
举例说明:在用户程序2中开启了UART1接收中断。当监控程序将控制权交给用户程序2后,用户程序2处于运行状态(UserFlag = 2)。如果此时UART1接收到数据,就会向MCU发出UART中断(0x4E)请求。MCU立即响应该中断,并跳转到中断向量表中该中断对应的中断服务程序的入口地址处(_Uart1_handler)运行。在该中断服务程序中根据UserFlag跳转到用户程序2的中断向量重定位表User2Vector[1](1表示在用户程序中的中断重定位号),并开始执行真正的中断服务程序。
3全局变量访问
在多用户编程系统中还需解决的问题是,监控程序中定义的变量如何在多用户程序中共享。在用户程序中可能需要访问监控程序中定义的全局变量,但由于用户程序和监控程序是分开编译的,所以用户程序无法直接访问监控程序中定义的全局变量。例如,将MCF52223的定时器中断设为1 ms,用户程序希望通过查询系统时钟的方式控制小灯每隔1 s亮灭一次。因此,必须在监控程序中添加全局变量,以记录中断的次数。用户程序查询该全局变量,记录第一次的值t1,并将再次读得的值t2和t1比较。当t2-t1>= 1 000时便点亮小灯,同时更新t1的值t1 = t2。有以下3种方法可实现全局变量的访问。
3.1寄存器
在MCF52223中可以使用的数据寄存器有D0~D7[3],主要用来保存操作数或运算结果等信息。它们的存在节省了存取操作数所需占用总线和访问存储器的时间。寄存器资源比较少,而且寄存器是CPU使用的,因此用户程序在使用前需要将寄存器的值进栈,用完后立即恢复。由于用户程序是不定期地访问寄存器,所以需要频繁地进出栈,而且在C语言工程中直接操作寄存器需要嵌入汇编代码,使用起来不方便,还会破坏程序的整体风格。
3.2RAM
RAM是指随机存取存储器,存储单元的内容可按需随意取出或存入,且存取的速度与存储单元的位置无关。这种存储器在断电时将丢失其存储内容,故主要用于存储短时间使用的程序。每个单片机上都集成了一定容量的RAM,用于程序的运行、变量的存储以及系统堆栈的开辟。程序中定义的全局变量都是在RAM中分得的一块空间,而变量名只是地址的代号,因而可以使用地址直接存取RAM。
3.3Flash
对Flash存储器的读写不同于一般的RAM读写,需要专门的编程。Flash有两种基本操作:擦除(Erase)和写入(Program)。擦除操作的含义是将存储单元的内容由二进制的0变成1;而写入操作的含义,是将存储单元的内容由二进制的1变成0。对Flash的写入相当于对其执行逻辑与的操作,逻辑与的结果即Flash的内容。在执行写入操作之前要确保该区域是空白的(存储单元内容为$FF),即同一块Flash擦除后只能写一次。因此,在写Flash之前一般都要先执行擦除操作。
虽然RAM的效率较寄存器低,但是比Flash提升了很多,而且可以用变量或指针来操作,使用比较简单。因而,最终确定使用RAM来实现多用户在线编程的全局变量共享。实现方法:定义unsigned short类型的指针指向地址为0x20000400所在的RAM区。
unsigned short *p;
p = (unsigned short *)0x20000400;
系统每毫秒产生一次定时器中断,在中断服务程序中将指针的值加1,即(*p)++。在用户程序中也可以定义指针,同样指定到地址为0x20000400所在的RAM区,也可以跟监控程序一样使用地址来共享。
4系统试验评估
随着机器人教育的普及,采用多用户程序在线编程技术的教育机器人开发平台随之而产生。教育机器人开发平台分为3部分:外围设备、主控板及软件平台。学生通过软件平台生成多个用户程序,通过USB将编译后的用户程序下载到主控板的不同用户空间中。可以利用按键选择不同的用户程序运行,搭配外围设备即可实现用户的功能。
在分析并解决了前面几个关键问题后,设计的监控程序完全能满足多用户在线编程的要求。通过使用指针的方法在多用户程序中共享监控程序中定义的全局变量,如本设计中的系统时钟。本文使用了USB接口,因而支持即插即用,并且高通信速率和有效的校验保证了用户程序快速、高效的下载,为多用户在线编程提供了高可靠性。
结语
多用户程序在线编程技术建立在监控程序的基础上,是对单用户程序在线编程技术的一种改进,使硬件资源得以充分利用。文中以MCF52223芯片为例设计的多用户程序在线编程系统,可稳定地应用于教育机器人开发平台。实践表明,多用户在线编程运行稳定、方便更新,具有一定的推广价值。但是有关在线编程技术的文献资料比较少,特别是多用户程序在线编程方面,因此,涉及的相关细节还需进一步研究。