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

2007-10-31 20:30 4801 4 5 分类: MCU/ 嵌入式

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


1.   软件中断SWI


SWI(software interrupt)软件中断,由用户定义的中断指令.可以用于用户模式下的程序调用特权操作指令.在实时操作系统中可以通过该机制实现系统调用.


一个 SWI 所做的一切就是把模式改变成超级用户并设置 PC 来执行在地址 &08 处的下一个指令!<?XML:NAMESPACE PREFIX = O />


编程异常通常叫做软中断.软中断是通讯进程之间用来模拟硬中断的一种信号通讯方式。中断源发中断请求或软中断信号后,CPU或接收进程在适当的时机自动进行中断处理或完成软中断信号对应的功能.


软中断是软件实现的中断,也就是程序运行时其他程序对它的中断;而硬中断是硬件实现的中断,是程序运行时设备对它的中断。


1.软中断发生的时间是由程序控制的,而硬中断发生的时间是随机的


2.软中断是由程序调用发生的,而硬中断是由外设引发的


3.硬件中断处理程序要确保它能快速地完成它的任务,这样程序执行时才不会等待较长时间


2.   软件中断使用的始末


2.1  SWI指令


SWI{cond} immed_24


其中,immed_2424位立即数


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指令的二进制代码。


注:软中断功能号为0x000x01的函数使用汇编语言写的,而其他的函数是用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中。


2OSIntCtxSw的实现


OSIntCtxSw


LDR R2, [SP,#20]


…//具体代码间参考文献[1]P218


3__OSStartHighRdy的实现


//具体代码间参考文献[1]P219


2.4.3.         在文件OS_CPU_C.C中编写软中断服务程序


为了使uC/OS-II的一些底层系统函数在调用时与处理器工作模式无关,所以在移植时采用软中断来实现.除了功能号0102的软中断函数是用汇编语言,其他的软中断函数都是用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/<?XML:NAMESPACE PREFIX = ST1 />2006/12/21/1451199.aspx

文章评论1条评论)

登录后参与讨论

用户1483121 2009-8-12 17:10

非常感谢,资料对我用处很大啊,不过我想问下楼主我是刚学ucos ii 的初学者 ,懂c,现在要用它来编程,要怎么学才会少走弯路,谢谢了希望能得到回复Q53044997
相关推荐阅读
用户110726 2007-10-31 22:31
UCOS-II移植ARM的读书笔记(12.11--12.25)
http://blog.csdn.net/zhhg_1220/ UCOS-II移植ARM的读书笔记(12.11) 真是很郁闷,昨天晚上边看移植代码边记下来的笔记不知道怎么回事在保存的时候竟然不见了。。...
用户110726 2007-10-31 20:43
ARM汇编的SWI指令软中断
从下面的一个ARM 汇编小程序要弄懂的以下三个问题:1).在ARM状态转到THUNB状态和BX的应用2).汇编的架构3).SWI指令的使用    AREA ADDREG,CODE,READONLY  ...
用户110726 2007-10-31 20:29
Luminary Micro半导体-LM3S101微控制器(超低价格的ARM芯片)
概述  Luminary Micro StellarisTM系列的微控制器是首款基于ARM® CortexTM-M3的控制器,它将高性能的32位计算引入到对价格敏感的嵌入式微控制器应用中。这些堪称先锋...
用户110726 2007-10-31 19:49
ARM9微控制器LPC3180的软硬件平台设计
来源:网络 作者:不详 发布时间:2007-03-02   摘要 介绍以Philips LPC3180微控制器为核心的嵌入式软硬件平台设计;对系统设计的硬件部分和软件部分进行详细的分析,并针对LPC3...
用户110726 2007-10-31 19:47
AVR单片机的RTOS-AVRX应用
来源:网络 作者:不详 发布时间:2007-03-02 摘  要:详细介绍AVR系列单片机的专用实时嵌入式操作系统AVRX的特点,并以ATmega16单片机为平台,结合AVR单片机应用实例分析AVRX...
我要评论
1
4
关闭 站长推荐上一条 /2 下一条