uc/OS II移植中软件中断的理解与应用

1.   软件中断SWI
SWI(software interrupt)软件中断,由用户定义的中断指令.可以用于用户模式下的程序调用特权操作指令.在实时操作系统中可以通过该机制实现系统调用.
一个 SWI 所做的一切就是把模式改变成超级用户并设置 PC 来执行在地址 &08 处的下一个指令!
编程异常通常叫做软中断.软中断是通讯进程之间用来模拟硬中断的一种信号通讯方式。中断源发中断请求或软中断信号后,CPU或接收进程在适当的时机自动进行中断处理或完成软中断信号对应的功能.
软中断是软件实现的中断,也就是程序运行时其他程序对它的中断;而硬中断是硬件实现的中断,是程序运行时设备对它的中断。
1.软中断发生的时间是由程序控制的,而硬中断发生的时间是随机的
2.软中断是由程序调用发生的,而硬中断是由外设引发的
3.硬件中断处理程序要确保它能快速地完成它的任务,这样程序执行时才不会等待较长时间
2.   软件中断使用的始末
2.1 SWI指令
SWI{cond} immed_24
其中,immed_24位24位立即数
2.2 ADS编译器中软中断的规定
ADS编译器规定,用户可使用关键字__swi作为前缀来声明一个利用软中断的调用,其格式如下:
__swi(功能号) 返回值类型名称(参数列表);
其中关键字__swi后面的括号中的字段叫做软中断的功能编号。系统是根据这个编号在软中断服务程序户中来确定应执行的程序段的。用户可以在用户程序中像调用一个普通函数那样实现软中断的调用。只是该“函数”没有普通函数那样明显的函数实现体。至于软件中断具体的函数实体后面会讲到。
利用软中断服务程序可以规避由于ARM处在不同工作模式时所造成的访问限制(如资源的访问限制)。
2.3 在Uc/OS-II中软中断来实现的函数的声明
函数注册软中断号
__swi(0x00) void OS_TASK_SW(void);                /*  任务级任务切换函数           */
__swi(0x01) void __OSStartHighRdy(void);           /*  运行优先级最高的任务         */
__swi(0x02) void OS_ENTER_CRITICAL(void);       /*  关中断                          */
__swi(0x03) void OS_EXIT_CRITICAL(void);         /*  开中断                           */
__swi(0x40) void *GetOSFunctionAddr(int Index); /*  获取系统服务函数入口         */
__swi(0x41) void *GetUsrFunctionAddr(int Index); /*  获取自定义服务函数入口      */
__swi(0x42) void OSISRBegin(void);                     /*  中断开始处理                   */
__swi(0x43) int  OSISRNeedSwap(void);               /*  判断中断是否需要切换         */
__swi(0x80) void ChangeToSYSMode(void);         /*  任务切换到系统模式            */
__swi(0x81) void ChangeToUSRMode(void);          /*  任务切换到用户模式            */
__swi(0x82) void TaskIsARM(INT8U prio);             /*  任务代码是 ARM 代码           */
__swi(0x83) void TaskIsTHUMB(INT8U prio);      /* 任务代码是THUMB           */
这些函数不是通常意义上的函数,只是可以让用户在应用程序中使用这些“函数名”去引发一个携带功能号的软中断SWI,即ADS编译器在编译这些函数时,把他们编译成SWI指令的二进制代码。
注:软中断功能号为0x00、0x01的函数使用汇编语言写的,而其他的函数是用c语言写的。具体代码见下面。
注: 遵照ATPCS函数调用标准,一个 SWI调用允许带1~4个字型参数和1~4个字型返回值,触发SWI调用时四个参数依次保存在R0~R3中,返回值也存于R0~R3内。所以在软中断服务程序中应函数所需要的参数按顺序保存到R0~R3中。
2.4 软中断具体实现始末
以两个具体的函数调用来说明软中断具体的实现。一个是任务级切换函数void OS_TASK_SW(void),一个是任务模式切换函数void ChangeToSYSMode(void).
2.4.1.         从启动代码中开始
硬件平台为ARM7内核。当有软中断发生(即调用2.2中某一个函数时)时,系统首先自动调转到0x0008处执行。
1、第一级中断向量
    AREA    Init,CODE,READONLY
 
    ENTRY
    b ResetHandler ;for debug
    b HandlerUndef ;handlerUndef
    b HandlerSWI    ;SWI interrupt handler
    b HandlerPabort ;handlerPAbort
    b HandlerDabort ;handlerDAbort
    b .             ;handlerReserved
    b HandlerIRQ
    b HandlerFIQ
2、宏展开
继续找HandlerSWI。
HandlerSWI HANDLER HandleSWI
3、内存第二级中断向量
再找HandleSWI。
^   _ISR_STARTADDRESS
HandleReset     #   4
HandleUndef     #   4
HandleSWI       #   4
HandlePabort    #   4
HandleDabort    #   4
HandleReserved #   4
HandleIRQ       #   4
HandleFIQ       #   4
现在我们知道软中断的服务程序跑到了内存中去了,我们可以编写相应的代码来实现不同功能号下的不同功能。
2.4.2.         在文件OS_CPU_A.S中编写软中断服务程序
1、软中断服务代码。
HandleSWI
    LDR    sp, StackSvc;
STMFD  sp!, {r0-r3, r12, lr};// STMDB,保护现场
MOV    r1,  sp    ;// 若SWI调用带参,将R1指向第二个参数
                      ;// 遵照ATPCS标准,第一个参数存于R0中
MRS    r3,  spsr
TST    r3, #0x20 ;//检查时ARM还是THUMB指令  
STMFD  sp!, {r0} ;// spsr入栈
LDRNEH r0,  [lr,# -2]  ;// THUMB指令时执行,获取SWI指令码
BICNE r0,  r0, #0xFF00 ;// 获取SWI number
;// r0 now contains SWI number
;// r1 now contains pointer to stacked registers
      LDREQ r0, r0, #0xFF000000;//ro中存放着软中断的功能号
      CMP    r0, #1;
      LDRLO pc, =OSIntCtxSw        ;//LDRLO=LDRCC r0=0时跳转到汇编语言处理
      LDREQ pc, =__OSStartHighRdy ;//r0=1时跳转到汇编语言处理
BL     SWI_Exception          ;// r0>1时跳转,调用C编写的SWI处理函数
LDMFD  sp!,  {r0-r3, r12, pc}^   ;// 恢复现场
我们可以看出当调用2.2中某一个函数并且函数具有两个参数时,函数的第一个参数存放在r0中,第二个参数存放在r1中。
2、OSIntCtxSw的实现
OSIntCtxSw
LDR R2, [SP,#20]
…//具体代码间参考文献[1]P218
3、__OSStartHighRdy的实现
//具体代码间参考文献[1]P219
2.4.3.         在文件OS_CPU_C.C中编写软中断服务程序
为了使uC/OS-II的一些底层系统函数在调用时与处理器工作模式无关,所以在移植时采用软中断来实现.除了功能号01、02的软中断函数是用汇编语言,其他的软中断函数都是用C语言编写的.
void SWI_Exception( int SWI_Num,//软中断功能号
int *Regs   //为指向堆栈中保存寄存器的值的指针
)
{
      OS_TCB *ptch;
      Switch(SWI_Num)// 具体代码间参考文献[1]P214
{
    case 0x02://宏 OS_ENTER_CRITICAL() 的代码
    case 0x03://宏 OS_EXIT_CRITICAL() 的代码
    case 0x80://宏 ChangeToSYSMode () 的代码
case 0x81://宏 ChangeToUSRMode () 的代码
case 0x82://宏 TaskIsARM () 的代码
case 0x83://宏TaskIsTHUMB () 的代码
default:break;
}
}

3.   参考文献
[1] 任哲.嵌入式实时操作系统uc/OS-II原来及应用.北京:北京航空航天大学出版社,2005.8
[2] Labrosse Jean J. 嵌入式实时操作系统uc/OS-II(第二版). 邵贝贝等译. 北京: 北京航空航天大学出版社,2003
[3] http://blog.csdn.net/zhhg_1220/archive/2006/12/21/1451199.aspx
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值