引言
目前,在面向应用的嵌入式体系结构的研究中,为了能同时利用通用处理器(CPU)的灵活性和专用集成电路(ASIC)的高效性,一些研究者将系统中性能要求较高的模块用FPGA等可编程器件实现,与通用处理器集成可重构片上系统。随着现场可编程门阵列(FPGA)技术的快速发展,可重构技术开始受到研究者们越来越多的关注。但是可重构计算的发展现状是硬件远远领先于软件,在可重构计算中需要一个操作系统来管理新的可重构硬件资源,屏蔽硬件细节,并向开发人员提供高层次的编程模型[1]。因此一些研究者将由可编程器件实现的任务模块抽象为硬件任务,并纳入可重构实时操作系统的统一管理,由可重构实时操作系统负责任务调度、系统资源管理以及任务间的通信和同步等工作。
迄今,对可重构系统任务间通信的研究取得了一些成果。例如,Miljan Vuletic等人在参考文献[2]中将纯软件任务环境的虚拟存储访问向可重构环境进行了扩展,以方便应用编程和移植;Philip Garcia等人在参考文献[3]中对硬件任务接口进行了研究,以实现对硬件任务的统一封装。但这些研究仅着眼于底层数据的交互,而没有考虑通信中伴随的上层任务间的同步和互斥逻辑;另外,张磊等人在参考文献[4]中对软/硬件任务互斥进行了研究,但没有考虑大量数据跨越CPU和FPGA边界的情况。因此,本文在这些研究成果的基础上,结合底层实现和上层逻辑对基于统一优先级调度的可重构系统中软/硬件任务间通信进行探讨。
1可重构系统中软/硬件任务间通信分析
1.1相关概念
硬件任务,是指由可重构硬件资源实现的功能模块,相对于软件任务具有以下特点:
① 硬件任务的数量受限于可重构资源的数量;
② 硬件任务可以实现微观并行;
③ 硬件任务通过配置可重构资源来建立,建立时间长,不可以忽略不计;
④ 由于硬件任务在运行的切换开销较大,因此不必像软件任务那样进行切换来分享CPU,而是可以独享相应的资源。
为了支持统一优先级调度,软/硬件任务可统一表示为Ti(ai,ei,di,ci,wi,hi)[5]。其中,ai表示任务到达时间,ei表示任务最坏运行时间,di表示任务完成截止时间,ci表示任务配置时间,wi和hi表示硬件任务的宽度和高度。
由于硬件任务和软件任务具有不同的特点,从而可将其中任务间的通信和同步分为3类,即软件任务(SWT)之间、软/硬件任务之间以及硬件任务(HWT)之间。
1.2分层的通信模型
对于任何一个操作系统来说,任务间的通信和同步都是必不可少的。系统中各任务的运行不仅与任务的应用逻辑相关还与系统的状态相关,而系统的状态又由系统中运行的多个任务决定,因此任务间的通信往往伴随着同步和互斥的实现。为了便于任务间的通信,从传统纯软件任务环境向可重构环境的扩展,将其分为逻辑机制和物理实现两个层次。其中逻辑层主要负责多个任务间同步控制以及数据的保护,与底层的数据交互无关;而物理层则负责底层数据交互的实现,即逻辑层和物理层以松耦合的方式组合,从而方便了系统的移植和通信机制的扩展。
就逻辑机制层而言,在传统的纯软件任务的环境中,运行于CPU上的多个软件任务具有宏观上并行微观上串行的特点,操作系统在对这些任务的资源共享和数据交互的管理上已有信号量、互斥量、消息队列等成熟的通信机制。但在可重构系统中,软件任务和硬件任务分别运行于CPU和FPGA上,软/硬件任务间及硬件任务间具有微观并行性,因此需要扩展这些通信机制对硬件任务的支持,以实现跨越CPU和FPGA边界的软/硬件任务间通信。这主要表现在针对不同类型的任务采取不同的后续措施上,同时向上层应用提供统一的通信接口。
而对于物理层的实现,考虑到分布式存储中消息传递方式实现的通信开销较大且实现复杂,采用图1所示的系统结构。CPU、FPGA以及系统主存挂接到总线上组成RSOPC。CPU除运行一定的用户软件任务之外,还负责提供操作系统服务,包括任务调度、资源管理、通信和同步管理等。操作系统通过统一的软/硬件任务视图——任务控制块来对各个任务进行管理。硬件任务(HWT)运行于FPGA上,并由FPGA给每个硬件任务提供一个统一的硬件任务接口(HTI)供操作系统和硬件任务的交互,同时每个硬件任务在CPU上有代理任务与其对应。而软件任务的代码和数据以及硬件任务的配置数据都存放于系统内存中, CPU通过片上总线读取存储器中的硬件任务配置数据对FPGA进行配置。
图1系统结构框图
为了方便应用编程和移植,系统主存和FPGA的局部存储器统一编址,且该地址由基址和偏移两部分组成。基址以页为单位,而偏移不超过页的大小,即设系统的地址空间为2n,页大小为2k,则基址的取值范围为[0,2n/2k],而偏移的取值范围为[0, 2k]。Main_Memory和Local_Memory分配有不同的基址,在编译器的支持下,全局数据和软件任务的局部数据存放于Main_Memory,而硬件任务的局部数据存放于Local_Memory。在应用层,任务可通过统一的全局地址访问数据,在物理实现上硬件任务只能直接访问Local_Memory的数据;而当其数据需跨越CPU和FPGA边界时,则通过如消息队列服务等固定的几种方式向OS发出申请,并由OS控制数据的迁移以及迁移前后被迁移数据地址在Main_Memory范围和Local_Memory范围的映射,地址的映射主要通过设置HWTI中的地址寄存器来实现,详见2.2.2节。在这种设计前提下,进行应用设计时不必关心任务的实现方式。
2可重构系统中消息队列通信机制
消息队列是一种灵活的通信机制,它允许一个任务或中断服务子程序向另一个任务发送以指针方式定义的变量或其他任务[6]。
2.1μC/OSII简介
μC/OSII是一个专门为计算机嵌入式应用设计的源码开放的可移植、可固化、多任务的占先式实时内核,提供基于静态优先级的抢占式调度,且具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点。在任务通信方面,μC/OSII提供了信号量、互斥量、消息队列、消息邮箱和事件标志组五种通信机制。
2.2消息队列通信实现的支持机制
2.2.1硬件任务接口与硬件任务代理
图2软/硬件任务间消息队列通信逻辑框图
软/硬件任务间消息队列通信的逻辑框图如图2所示。软/硬件任务分别通过自身和代理调用OSQ_Request向OS申请消息队列服务,使得在通信逻辑层OS可将软/硬件任务同等看待。这方便了现有通信逻辑向可重构系统的扩展,同时OS提供的通信服务由软件实现相对于硬件实现更具灵活性。
由图2可见,硬件任务在申请消息队列服务时需要硬件任务接口(HWTI)、硬件任务代理(HWTAgent)和中断的支持。一次典型的消息申请消息服务的执行过程可描述为:
① 硬件任务将申请的服务类型及参数等放入HWTI中的相应寄存器;
② 硬件任务向CPU发送中断;
③ CPU响应中断,在中断服务程序里唤醒硬件任务代理;
④ 硬件任务代理获得调度,调用系统调用以取得消息,将消息在Local Memory的地址存入HWTI中的地址寄存器中并唤醒硬件任务;
⑤ 硬件任务继续执行。
HWTI是用户硬件任务和操作系统之间的桥梁[1],由一组寄存器组成,主要包括控制寄存器、状态寄存器、参数寄存器、地址寄存器等。
HWTAgent本质上是一个运行于CPU上的软件任务,它充当了OS与运行于FPGA上的硬件任务的桥梁。HWTAgent的存在使得在通信逻辑层OS可以将硬件任务和软件任务同等看待,从而方便了软/硬件任务统一优先级的调度,而HWTAgent对应代码段的执行则实现通信物理层功能。HWTAgent的设置同时也是出于这样一种考虑:中断服务程序应执行尽可能少的代码,否则将影响系统的实时性。由于在消息队列通信中需要设置HWTI中的寄存器,同时可能涉及大量数据的迁移,若将这部分工作由中断服务来完成,将会影响对后续高优先级硬件任务请求的响应。而设置HWTAgent后,中断服务程序只需将请求类型放入TCB然后激活HWTAgent即可,而将其他的任务交由软件任务HWTAgent来完成,从而能尽快响应后续高优先级硬件任务的请求。
2.2.2硬件任务对全局数据的访问
由前所述,数据访问的同步和保护等服务由运行于CPU上的OS提供。当硬件任务向OS申请消息时,若分配得的消息存在于Main_Memory上,则HWTAgent会把消息从Main_Memory迁移到Local_Memory;而当数据迁移完成后HWTAgent还需完成消息地址的转换,即将硬件任务当前可用的消息在Local_Memory中的地址存入HWTI中的地址寄存器中。由于Main_Memory和Local_Memory统一编址,OS控制着系统的存储布局信息,因此地址的转换是可以实现的。
2.3可重构系统中消息队列通信的实现
针对消息队列的操作主要有4种,即创建消息队列、删除消息队列、申请消息和发送消息。这里规定消息的申请不能由中断服务子程序调用,主要是因为消息的申请可能引起任务的阻塞,而消息队列的创建和删除只能由软件任务调用。这也是可以理解的,因为硬件任务一般作为大数据处理的加速器使用,而应用的控制逻辑仍由软件任务实现。
由1.2的叙述可知,需扩展消息队列通信对硬件任务的支持,同时为了维护逻辑层与物理层的松耦合性,有关数据迁移和地址转换的部分均由HWTAgent完成。采取如下具体措施,以实现基于统一优先级的软/硬件任务间消息队列通信:
① 在有关消息队列的内核部分增加一个查找被阻塞任务中最高优先级的系统调用OSQFindHighPrio(),若消息队列当前有被阻塞任务则返回其中具有最高优先级任务的优先级,否则返回1;
② 针对硬件任务服务申请的中断服务程序只需调用OSAgentRdy()唤醒请求任务对应的代理任务,OSAgentRdy()定义为OSAgentRdy(INT8U reqType, INT8U tid, void *param),其中reqType为请求类型,tid为请求任务的id,param为请求附带的参数;
③ HWTAgent获得调用后根据情况执行后续操作(针对因申请消息队列服务而唤醒的部分),其执行伪代码如下(记当前操作的消息队列为Q,发出申请的任务为T,具有最高优先级的被阻塞任务为T1):
--get the reqType;
if reqType==SEND_Q then
--find T1's priority by calling OSQFindHighPrio(Q);
--ifT1 is a SWT or priority is negative then
malloc a block named msg in Main_Memory to storage the message;
transport the message from Local_Memory to Main_Memory;
--OSQPost(Q,msg);
else
--active T1's agent;
end if
else if reqType==REQUEST_Q then
--get message by calling OSQPend();
--if the message is stored in Main_Memorythen
transport the message from Main_Memory to Local_Memory;
translate the message's address from Main_Memory domain to Local_Memory domain;
end if
--active T;
end if
以上执行过程可描述如下:判断申请的服务类型;若是发送消息请求则调用OSQFindHighPrio()查找被阻塞的最高优先级;若Q中没有被阻塞的任务或被阻塞任务中具有最高优先级的任务是SWT,则需进行数据迁移;利用迁移后的消息地址调用OSQPost;否则Q中具有最高优先级的被阻塞任务为HWT,不需数据迁移而直接激活该任务;否则若是获取消息请求则调用OSQPend()以获取消息;若获得的消息存放于Main_Memory,则需进行数据迁移;由于获得消息而激活发送请求的硬件任务T。
3模拟实验及分析
本文针对由CPU和FPGA组成的可重构系统提出了一种分层的软/硬件任务间通信方式,并在其上实现了消息队列通信。考虑到CPU具有更高的灵活性而FPGA具有更高的数据量处理效率,将硬件任务作为大数据处理的加速器使用,而通信的系统控制部分由运行于CPU上的OS负责。这一实现具有以下优点:
① 由软件实现系统控制更具灵活性,分层的通信结构使系统层次更加清晰,方便移植;
② 向上层应用程序员屏蔽软硬件底层差异,使得应用程序员可以将注意力集中于应用逻辑的处理上;
③ 硬件任务代理的设置减轻了中断服务程序的压力,保证了对后续高优先级硬件任务请求的响应能力。
为了证明HWTAgent能保证后续高优先级硬件任务的请求能得到及时响应,现对有HWTAgent和无HWTAgent两种情况下同级中断的响应时间进行比较。记消息长度为L,使用和不使用HWTAgent时响应时间分别为t1和t2,单位为CPU时钟周期数。
图3为使用与不使用HWAgent下对后续硬件任务请求的响应时间随消息长度改变的情况。
由图3可知,不采用HWTAgent时最坏情况下的响应时间会随消息长度的增加而延长;而使用HWTAgent后,响应时间为一固定值,且接近最好情况的响应时间。可见,HWTAgent可有效地保证对后续高优先级硬件任务请求的响应能力。
图3响应时间变化
结语
本文对可重构系统中任务间的通信机制进行了探讨,提出了一种分层的通信机制,方便了通信逻辑层的扩展以及通信物理层的移植,并在其上实现了消息队列通信,且用模拟实验证明了其有效性。