基于ARM7支持触摸屏和实时操作系统的开发与应用
2010-10-18李广荣宗文波韩建超杨丹于海滨刘锏泽
李广荣 宗文波 韩建超 杨 丹 于海滨 刘锏泽
摘要:本文介绍了μC/OS-II嵌入式实时操作系统和μC/GUI在ARM7处理器上的移植方法,以及如何利用嵌入式操作系统进行应用程序的开发和管理各种任务。重点讨论了μC/OS-II实时操作系统的移植方法和μC/GUI的移植技术,并提供了一种简单有效的去除触摸屏抖动的方法;最后通过应用实例对任务的划分和界面的操作进行了说明。
关键词:触摸屏;μC/GUI;μC/OS-II;ARM7
概述
随着信息技术的发展,支持图形界面的触摸操作和实时操作系统相结合的应用系统已经越来越广泛地应用到航空航天、军事、消费类电子、通讯设备等领域。mC/OS-II操作系统是一种占先式、实时操作系统(RTOS),由于其内核可拆减、可剥离性,使得它在实时控制领域中有着广泛的应用。它不仅减小了因为系统硬件设计缺陷带来的不可靠因素,而且增强了系统的控制实时性,从软件方面进一步增强了ARM控制系统的性能。另外,新版本的mC/OS-II已经通过了FAA认证,很适合应用于对实时性要求很高的嵌入式工业控制领域,如目前应用较广泛的军用战斗机、攻击机和火控系统等。
支持图形界面操作(mC/GUI)是一种较为流行的人机交互系统,它能够提供了友好的人机交互平台,使得微处理器成为大多数人都能够使用和接受的工具。与PC机不同,由于mC/OS-II基本为“黑盒”式操作系统,对人机界面的控制与开发需比较复杂的编程技术和时序控制技术。ARM7嵌入式实时控制系统对mC/GUI的要求更高,包括轻型、占用资源少、高性能、高可靠性及可配置等。因此,如何将ARM7、mC/GUI、mC/OS-II、触摸屏驱动和应用程序有机的结合起来,在ARM7上进行运行并完成用户想实现的任务,成为在嵌入式操作系统开发中的一项关键技术。
mC/OS-II嵌入式操作系统的移植
mC/OS-II作为操作系统的内核,主要的任务就是完成多任务之间的调度和同步,协调各个硬件源不会冲突。与其它嵌入式操作系统相比,它具有系统透明、可拆减、接口简单的特点。下面就如何在S3C44B0进行操作系统移植和修改作简要的描述:
(1)重新修改OS_CPU.H文件
a)定义数据类型:mC/OS-Ⅱ不使用C语言中的short、int、long等与处理器类型有关的数据类型,而代之以移植性强的数据类型,这样既直观又便于移植;
b)定义堆栈增长类型和ARM运行的模式:虽然ARM处理器对堆栈向上与向下的两种增长方式都予以支持,但由于编译器ADS仅支持堆栈从上往下,并且必须是满递减堆栈,所以在文件中用来定义堆栈增长方式的常量OS_STK_GROWTH 的值为1;
c)需对外部函数声明:如在mC/OS-II.h头文件中,有些要移植的函数已经声明,包括:OSTaskStkInit()、OSIntCtxSw(void)、OSStartHighRdy(void) 。
(2)修改OS_CPU_C.C文件
a)任务堆栈初始化函数OSTaskStkInit():在编写任务堆栈初始化函数OSTaskStkInit()之前,必须先根据处理器的结构和特点确定任务的堆栈结构;
b)钩子函数:mC/OS-II为了用户在系统函数中书写自己的代码而预置了一些钩子函数(如OSTimeTickHook),这些函数在移植时可全为空函数,可根据用户的需要添加。
(3)重点编写OS_CPU_A.S文件a)开/关中断函数:在ARM7处理器核中可利用改变程序状态寄存器CPSR中的相应控制位实现;
b)OSStartHighRdy(void):OSStart()函数调用OSStartHighRdy()来使就绪态任务中优先级最高的任务开始执行;
c)OS_TASK_SW(void):μC/OS-II通过调用OSSched()函数来完成任务调度的,OSSched()先将最高优先级任务的地址装载到OSTCBHighRdy,再通过调用OS_TASK_SW()执行任务级的任务切换,OS_TASK_SW主要完成保护现场,完成用于的任务,恢复现场;
d)OSIntCtxSw(void):OSIntExit()通过调用OSIntCtxSw(),在中断服务程序中执行任务切换功能。
e)时钟节拍函数:在本移植中,只使用了ARM的IRQ中断。由于不同的ARM芯片的中断系统并不完全一样,因此不可能编写出对所有使用ARM核的处理器通用的中断及节拍移植代码,但是这是后续任务管理中重点需要操作系统进行处理的,OSTickISR的实现代码见程序清单。
程序清单 OSTickISR()
OSTickISR
STMFD SP!, {R0-R3,R12,LR}
BL OSIntEnter
BL user_function ;调用用户
处理的中断处理程序
BL OSIntExit
LDMFD SP!,{R0-R3,R12,LR} S3C44B0触摸屏驱动程序编制
本文采用固定参考电压模式,在驱动程序开发过程中,需要关注时钟端、输入端和输出端的时序特性。首先检测PENIRQ是否为低电平,只有触摸屏有接触时此位才会为低电平。利用软件模拟DIN、DOUT和DCLK上的三线串行传输时序,将读取的X或Y坐标数值的控制字串行送人ADS7843,然后再从对应的函数读出该坐标值,获取坐标值的源程序如下:
int TOUCH_X_MeasureX(void)
{
X=ReadTouchXY(CHX);
return X;
}
int TOUCH_X_MeasureY(void)
{
Y=ReadTouchXY(CHY);
return Y;
}
其中,ReadTouchXY()函数通过TOUCH_X_MeasureX(void)、TOUCH_X_MeasureY(void)读取对应坐标的X、Y轴的电压值,并送入主控程序进行坐标转化,得出当前触摸屏按压的位置。
int ReadTouchXY(unsigned char
command)
{
//根据command参数,进行X、Y向触摸点选择、去抖、位置的计算等
return ack;//返回触摸屏对应位
置值;
}
mC/GUI及与操作系统的接口
mC/GUI是运行于操作系统之上的程序,它既需要与操作系统协调,又需要与各种输入/输出设备协调,即通过输入设备接收用户请求,通过输出设备发送微处理器的处理结果。因此,mC/GUI的接口主要包括两个:与操作系统的接口和与输入/输出设备的接口,这也正是在移植mC/GUI的过程中所要解决的关键问题。mC/GUI与mC/OS-II结合应用时通过上锁和解锁来解决资源互斥的问题,其过程是通过在关键区域入口设置GUI_X_Lock()以获得专一访问权,用完后在出口处设置GUI_X_Unlock()让出资源,达到多个GUI任务对同一数据在关键区域内访问的互斥。
在mC/GUI移植到mC/OS-II的过程中,需要利用操作系统的资源来实现GUI所需要的功能,即利用μC/OSII提供的时间管理、任务管理和资源共享机制来实现μC/GUI中相应的功能,具体要实现以下函数的重新定义:
(1)时间函数
GUI_X_Delay() //延迟指定的时间段后返回
GUI_X_ExecIdle() //视窗管理器的非堵塞函数调用
GUI_X_GetTime() //返回当前
系统的时间,以毫秒为单位
(2)内核接口函数
GUI_X_InitOS() //初始化内核
接口模块
GUI_X_GetTaskID() //返回一个
当前任务/线程唯一的32位标识符
GUI_X_Lock() //给GUI上锁
GUI_X_UnLock() //解锁GUI
GUI_X_Log() //返回调试信息
(3)LCD底层驱动程序要使mC/GUI能够在目标系统上运行,首先要对mC/GUI进行配置和修改,也就是移植。移植工作主要是指对配置头文件中的宏定义根据具体情况进行修改,包括LCD宏和LCD控制器宏。使用mC/GUI库函数时,必须在主函数前调用头文件“gui.h”,并根据需要做适当的修改。值得注意的是,在此文件的预定义语句中,必须将GUI_SUPPORT_TOUCH设为1。如果需要在屏幕上显示中文,除了添加中文字库到工程中外,还需要将GULDEFAULT_FONT设为&GULFontHZ12,HZ12代表使用的中文字体。如果需要在mC/GUI的控件中使用中文,也需要在控件的预定义语句中作相应的修改。由于ARM7芯片S3C44B0X内部集成了LCD控制器,LCD底层驱动程序主要是设计与LCD屏相关的参数以及其特殊的控制寄存器,主要包括以下的参数和寄存器:
#de ne SCR_XSIZE (640)
//LCD水平尺寸
#de ne SCR_YSIZE (240)
//LCD垂直尺寸
#de ne LCD_XSIZE (640)
//LCD水平分辨率
#de ne LCD_YSIZE (240)
//LCD垂直分辨率
#define ARRAY_SIZE_COLOR (SCR_XSIZE/1*SCR_YSIZE)
//LCD水平与垂直比例
#define HOZVAL_COLOR (LCD_XSIZE*3/8-1)
//LCD水平字节尺寸
#de ne SCR_XSIZE (640)
//LCD水平尺寸
#de ne SCR_XSIZE (640)
//LCD水平尺寸寄存器的定义根据不同的微处理器和LCD颜色、尺寸等来定义,这里以S3C44B0X说明:
rLCDCON1=(0)|(2<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_COLOR<<12);
rLCDCON2=(LINEVAL)
|(HOZVAL_COLOR<<10)|(10<<21);
rLCDSADDR1= (0x3<<27)|(((U32)frameBuffer>>22)<<21)|M5D((U32)frameBu er>>1);
rLCDSADDR3= (LCD_XSIZE/2)|(((SCR_XSIZE-LCD_XSIZE)/2)<<9);
嵌入式操作系统下应用程序的开发
在嵌入式操作系统下开发基于ARM7的应用程序主要是进行任务的划分,根据每个任务的紧急程度建立不同优先级,下面就任务划分的原则和实例进行说明:
任务划分原则
将一个软件系统分解成并行任务时,主要考虑系统内功能的异步性。通过分析数据流图中的变换,确定哪些变换是并行的,哪些变换本质上是顺序执行的。通过这种方法,一个变换对应一个任务,或一个变换包括几个任务,同时应遵循如下原则:
● I/O依赖性:由于I/O速度的限制,对它操作的程序应独立为一个任务;
● 时间关键性:将有时间关键性的功能分离出来,组成独立的任务,赋予高优先级;
● 计算功能:计算功能要占用较多CPU时间间,应赋予他们较低的优先级;
● 功能内聚:将紧密相关的功能组成一个任务,使各种功能共享资源或相同事件的驱动;
● 时间内聚:将在同一时间内完成的任务,即使功能不相关,组成一个独立的任务;
● 周期执行功能:相同周期内执行的各功能组成一个任务,频率高的赋予高优先级。
应用实例
本文以实际项目为例进行分析,在本项目中触摸屏作为输入设备、系统检测输出窗口,通过控制器嵌入mC/OS-II操作系统和mC/GUI配合使用实现完成相应按钮指令的功能,并在后台的特定任务中完成各种中断、计算、通讯等功能。因此进行了如表1所列的任务划分和定义。
触摸屏的应用程序可以根据触摸屏的实际使用情况来编写,但在编写时应该注意模块化的编程思想,以便它能作为一种输入平台简便的移植到相关的应用中。本文编写了一个泵的控制系统作为触摸屏应用设计的实例。利用图形软件mC/GUI编写的控制系统操作界面如图1所示,当用触摸笔或者手指直接点击图中可编辑的按钮控件(如最高压力、设定流量和设定时间),弹出参数输入对话框,如图2所示。mC/GUI的设计具有模块化的特点,在不同的模块中包含了不同的层,比如LCD驱动包含了所有与LCD的接口。同样,mC/GUI也提供了通用触摸屏的应用程序接口(API),应用程序可以通过将它的函数库添加到工程中来方便的使用。
结语
在mC/OS-II实时操作系统和ARM平台上开发应用软件已经成为现代工业领域热点,可以大大地降低软件程序编写的时间和任务难度,提高了各模块的独立性,缩短开发周期,并且系统具有更好的稳定性、可移植性和可维护性。本文以实际的项目为应用背景,开发的基于ARM7支持触摸屏(mC/GUI)的实时操作系统(mC/OS-II)具有良好的人机交互界面,完善的驱动、控制、显示、检测和计算功能,支持单机和网络控制运行。