为了实现软硬件任务的协同调度,必须修改uc/os-ii的代码,使其能够对硬件任务有所控制。
一、总体设计
区分软件任务和硬件任务,软件任务跑在PPC上,硬件任务跑在FPGA上。用ISE工具生成硬件任务的bit流,放到CF卡上。操作系统对硬件任务的管理是通过创建硬件任务时以代理进程的形式实现。代理进程负责硬件任务bit流向内存的load、接受硬件任务在FPGA上运行时的通信(以中断的形式实现)、管理FPGA资源等。
软件任务分配了64个优先级,每个优先级对应一个软件任务;硬件任务也分配64个优先级,每个优先级对应一个硬件任务。硬件任务的调度策略借鉴软件任务的调度策略,实现O(1)调度。
调度的时候,先选择一个优先级最高的软件任务,然后在选择一个优先级最高的硬件任务,将这两个任务的优先级进行比较,选择优先级最高的任务占用CPU,从而实现软硬件任务的协同调度。(修改OSPrioCur与OSPrioHighRdy的类型为void *,增加两个全局变量TaskTypeCur和TaskTypeHigh分别指示当前运行的任务和选出的最高优先级任务是软件任务还是硬件任务)。
硬件任务的下载、运行过程是可抢占的。实现机制是:uc调度更高优先级的硬件任务,并且向下载器发送了下载信号。
二、硬件任务的代理进程
在oc/os-ii的基础上,增加硬件任务的控制块HW_TCB,其中包含硬件任务的优先级、咱用的FPGA的资源、硬件任务状态、事件控制域、消息等内容。每一个HW_TCB对应一个硬件任务的bit流,他们具有相同的优先级。
三、硬件任务的模型
void HWTask( void *hw_arg ){
char *comm_flag;
char *final_flag;
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
/*借助XilinxEDK的库下载bit流,将来要用硬件实现下载器,此处应改为发送下载命令、接受下载完成中断、发送启动任务命令*/
Loader(hw_id);
/*硬件任务在FPGA上运行了,修改系统中FPGA资源的管理。可以放入中断处理函数中*/
if( FPGAReplace -> FPGARunningPrio < OSTCBCur -> HWTCBPrio )
FPGARelace = OSTCBCur -> FPGAField;
OSTCBCur -> HWStat = HW_DOWN_KO;
OnFPGATask++;
print( "Have finished downloading %d bitstream\n", (INT8U)hw_arg );
/*挂起等待硬件任务运行完毕*/
final_flag = OSQPend( HW-task run over );
OSTCBCur -> HWStat = HW_FINI_KO;
print( "HW-Task %d is finished, quiting...\n", (INT8U)hw_arg );
OSTaskDel( HW_PRIO_SELF );
}
四、FPGA资源的管理
typedef struct fpga_cb{
INT8U FPGA_NO; /* FPGA slot source */
INT8U HWRunningPrio; /* HW task running on current slot */
struct fpga_cb *FPGANext; /* Pointer to next FPGA_CB in free list */
struct fpga_cb *FPGAPrev; /* Pointer to previous FPGA_CB in free list */
}F_CB;
可重配置资源的使用是以FPGA上的slot为单位的,所以,对FPGA的控制需要知道其slot号。
FPGA资源组织成双向链表,使用的时候从头部取出空闲的FPGA slot,回收时将空闲slot插入表头。当所有的slot都被占用,并且当前又有优先级更高的硬件任务到来时,需要替换出FPGA上优先级最低的硬件任务,因此,需要维护一个指针,当FPGA slot用完时,指向优先级最低的硬件任务占用的slot,将其分配给高优先级待下载任务。(当待下载的硬件任务所需要的slot资源多于一个slot时,需要修改这个全局的指针为按照硬件任务优先级由低到高排序的链表,将最低优先级的任务在用的资源交给待下载任务。而且待下载任务的优先级要高于所占用的所有低优先级的任务)。
FPGA资源的维护可以放在下载完毕的中断处理服务函数里实现。
/*modified 25/6/2009*/
借鉴linux2.6内核,对空闲的FPGA资源用位图进行管理。
int FPGA_bitmap; //初始时,置为全1,没使用一块,对应位清0
查找空闲块:find_free_source(){if(FPGA_bitmap) return __ffs(FPGA_bitmap);}
使用一个FPGA资源:FPGA_bitmap &= 1<
释放一个FPGA资源:FPGA_bitmap |= 1<
五、事件管理
uc将会发给FPGA的消息有:下载信号、启动信号、硬件任务请求资源的地址
FPGA发给uc的消息有:下载完成、请求资源、任务结束
个人认为事件可以不区分软件或是硬件,所以,可以用uc/os-ii自带的事件控制块和消息队列通信机制。
需要注意一点的需要把硬件任务的事件掩码加入ECB中,因为,软硬件有相同的优先级,由事件掩码计算出来的高优先级等待任务必须区分软硬件任务。
所以,可以考虑uc/os-ii的事件处理策略,但是,软件任务来的时候修改软件掩码部分,硬件任务来的时候修改硬件的掩码部分。由此带来的其他信息的改动也要随之修改。(此部分未能着手)
六、中断处理
需要考虑的中断有:硬件bit流下载完毕的中断、向uc请求资源的中断、任务结束中断。每个中断处理函数中需要完成硬件任务状态的修改、硬件资源的维护、消息队列的维护。(未能着手)
七、硬件任务的切换
硬件任务在切换的之前需要先把当前slot上的任务的寄存器的值保存起来,以便以后再次运行时,从当前状态继续。目前有两种想法,一是开辟保存硬件寄存器的全局变量,每次在新任务下载前把硬件寄存器保存起来,这样会带了系统的开销也会占用CPU资源;二是在任务切换的时候,判断若是将要使用的slot上有硬件任务正在运行,则置一个标志,修改任务切换函数,标志为1时,连同硬件寄存器一起保存在硬件任务的堆栈中。这样做将要修改大量的代码,而且有可能会涉及到体系结构部分,难度较大。
阅读(1139) | 评论(0) | 转发(0) |