2009年12月31日星期四

深入DSP/BIOS的API函数 - 软件中断管理SWI

SWI模块管理软件中断服务程序。这些中断服务程序与HWI硬件中断服务程序有密切关系。一般情况下,会将日常的大多数处理函数放到这些软件中断服务程序中管理运行。


一、SWI模块概述


在DSP/BIOS内核中,系统管理并运行的线程分为四个等级:硬件中断服务程序、软件中断服务程序、任务和后台空闲函数,优先级依次降低。每个软件中断服务程序都对应一个函数,当然,每个软件中断夜可以单独设置优先级。高优先级的软件中断会抢占正在执行的低优先级的软件中断(因此可以说DSP/BIOS是一个基于优先级的抢占式实时内核)软件中断都是通过DSP/BIOS内核的API调用来启动。一旦启动了一个SWI对象,此时,系统将为该SWI对象中的函数创建一个运行时间表。因此,当一个软件中断被启动后,其对象函数不一定会立即执行,而是会按照时间表在执行队列中根据优先级排队等候运行。DSP/BIOS根据软件中断优先级来判断是否要暂停当前运行的线程。
为了便于控制,系统为每个SWI对象都设置有一个16位的邮箱(Mailbox),可以利用邮箱的值有条件的启动这个软件中断。系统内核会自动维护邮箱的管理。DSP/BIOS内核提供了SWI_disable和SWI_enable操作来禁止或允许软件中断。同时还为软件中断设置有15个优先级,最高优先级为SWI_MAXPRI(14),最低优先级为SWI_MINPRI(0),0优先级为KNL_swi对象保留,KNL_swi对象的任务是执行任务调度程序,该对象由内核自动创建,高优先级的软件中断会打断正在运行的低优先级的软件中断。如果启动的两个软件中断的优先级相同,那么先启动的软件中断会先执行。

中断线程(包括硬件中断和软件中断)都是使用相同的堆栈来执行的。当中断发生时,新的线程就会添加到栈顶,系统会执行一次任务切换(Context
Switch)。由于高优先级软件中断会打断低优先级的软件中断的运行,所以SWI模块在运行高优先级软件中断前会自动保存寄存器中的内容。在高优先级软件中断运行完成后,寄存器会恢复原来的内容,以便继续运行原来的低优先级中断。如果没有启动其他高优先级的软件中断,低优先级的软件中断就会运行。DSP/BIOS内核虽然具有抢占的特点,但如果没有导致任务切换的API函数调用,系统则不会主动切换道其他线程去执行的。(理解这点在实际应用中很重要,即如果现在运行的是低优先级软中断对应的函数,如果你不在函数中调用如SWI_post()启动更高优先级的软件中断或启动了比自身低的优先级中断,则当前软中断就不会被打断,执行直到退出)。

个人经验:尽量不要在一个软中断对应的函数中去启动另一个比其本身优先级高的软件中断,因为根据抢占原则,其本身将被打断,从而CPU转去执行高优先级软中断对应的函数,低优先级的实时性将得不到保证,当有多级优先级及系统复杂情况下甚至引起系统瘫痪。也不要设置很多的优先级。当然这也不是绝对的,如果系统规划的好,利用好软中断的基于优先级抢占式的特点会大大简化你的设计。

二、LOG模块配置


软件中断可以在DSP/BIOS的配置文件中静态说明。打开DSP/BIOS配置文件,展开"Scheduling"选项,即可选择SWI模块。
comment:添加一段注解来说明该SWI对象。
function:该软件中断对象将调用的函数名。
priority:显示SWI对象的优先级。
mailbox:设置邮箱的初始值。
arg0,arg1:软件中断函数的两个指针类型变量。该变量可以在启动运行软件函数时由内核传递给该函数。

三、LOG模块API函数说明


1、SWI_andn:该函数提供的参数与邮箱值做"与"运算,若邮箱为0,则启动该软件中断;
2、SWI_dec:邮箱值减1,若邮箱值为0,则启动该软件中断,并恢复邮箱到初始值;
3、SWI_disble:禁止软件中断;
4、SWI_enable:允许软件中断;
5、SWI_getmbox:返回邮箱的值,注意该函数只能在软件中断函数中调用;
6、SWI_getpri:返回软件中断优先级;
7、SWI_inc:启动该软件中断,并对邮箱值加1;
8、SWI_or:启动该软件中断,并且邮箱值与该函数提供的参数做"或"运算;
9、SWI_post:启动软件中断;
10、SWI_raisepri:将软件中断优先级升高;
11、SWI_restorepri:恢复软件中断的优先级;
12、SWI_self:返回SWI对象的地址。

没有评论: