xlsbz 发表于 2010-5-27 21:32:49

关于如何禁止、启动IRQ FIQ?

弄的是AT91SAM7A3的。没有操作系统。
下面是启动代码关于设置模式的结尾部分

// Enter Supervisor Mode and set its Stack Pointer
                MSR   CPSR_c, #Mode_SVC|I_Bit|F_Bit
                MOV   SP, R0
                SUB   R0, R0, #SVC_Stack_Size

// Enter User Mode and set its Stack Pointer
                MSR   CPSR_c, #Mode_USR   //启动IRQ FIQ
                MOV   SP, R0
// Enter the C code
                LDR   R0,=?C?INIT
                TST   R0,#1       ; Bit-0 set: main is Thumb
                LDREQ   LR,=exit?A; ARM Mode
                LDRNE   LR,=exit?T; Thumb Mode
                BX      R0
                ENDP

然后进入main函数


void main (void)
{
//打算在这里禁止IRQ FIQ


//打算在这里初始化串口啊之类的

//打算在这里开启IRQFIQ

      while (1){
            代码
      }

}


我们知道最主要是 要修改CPSR寄存器。并且一定要从特权模式修改。

请问大家关于模式转换有什么好的建议么?
====================================================
比如说弄成这样行不行?(我对Supervisor不怎么了解)

// Enter Supervisor Mode and set its Stack Pointer
                MSR   CPSR_c, #Mode_SVC//禁止IRQ FIQ
                MOV   SP, R0


// Enter the C code
                LDR   R0,=?C?INIT
                TST   R0,#1       ; Bit-0 set: main is Thumb
                LDREQ   LR,=exit?A; ARM Mode
                LDRNE   LR,=exit?T; Thumb Mode
                BX      R0
                ENDP

然后进入main函数


void main (void)
{
//设置为Supervisor并禁止IRQ FIQ


//打算在这里初始化串口啊之类的

//设置为user模式并开启IRQFIQ

      while (1){
            代码
      }

}


==========================================================================

大家都是怎么弄的?
多谢!!!

xlsbz 发表于 2010-5-28 20:01:18

怎么没有人帮助我!!入门新手!多谢各位指点

xlsbz 发表于 2010-5-29 00:18:26

多谢各位的阅览

我想这样应该很好!

如下:

// Enter Supervisor Mode and set its Stack Pointer
                MSR   CPSR_c, #Mode_SVC | I_Bit | F_Bit   //禁用FIQ 模式 禁用IRQ模式
                MOV   SP, R0

// Enter the C code
                LDR   R0,=?C?INIT
                TST   R0,#1       ; Bit-0 set: main is Thumb
                LDREQ   LR,=exit?A; ARM Mode
                LDRNE   LR,=exit?T; Thumb Mode
                BX      R0
                ENDP

然后进入main函数


void main (void)
{

//打算在这里初始化串口啊之类的

//采用读--修改--写的方式 改变CPSR的值 使其处于USR模式 并使能IRQ 禁止FIQ (FIQ不想用,就禁止了吧)

      while (1){
            代码
      }

}

当然之所以这样做的理由有(1)据说linux就是用SVC模式进行中断嵌套的,所以我这里用SVC模式好
                        (2)看了最新的MDK官方库给的头文件 最后的模式是SVC模式。我想给这种模式肯定是有理由的。
                        (3)据说周立功的程序在SWI中断里面改CPSR,而SWI和超级用户模式可以看做相同的意思

tangwei039 发表于 2010-5-29 08:18:53

只有软中断可以进入特权模式,然后去禁止中断,或打开中断
你可以在你启动代码加入:
;软中断
SoftwareInterrupt                       

;//增加开/关中断处理                              
      CMP   R0, #4
      LDRLO   PC,
      MOVS    PC, LR

SwiFunction
      DCD   IRQDisable       ;0
      DCD   IRQEnable      ;1
      DCD                FIQDisable               ;2
      DCD                FIQEnable               ;3

IRQDisable
      ;关IRQ中断
      MRS   R0, SPSR
      ORR   R0, R0, #I_Bit
      MSR   SPSR_c, R0
      MOVS    PC, LR

IRQEnable
      ;开IRQ中断
      MRS   R0, SPSR
      BIC   R0, R0, #I_Bit
      MSR   SPSR_c, R0
      MOVS    PC, LR
      
FIQDisable
      ;关FIQ中断
      MRS   R0, SPSR
      ORR   R0, R0, #F_Bit
      MSR   SPSR_c, R0
      MOVS    PC, LR

FIQEnable
      ;开FIQ中断
      MRS   R0, SPSR
      BIC   R0, R0, #F_Bit
      MSR   SPSR_c, R0
      MOVS    PC, LR


然后在你.C文件中可以这样写

/**************************************中断设置部分*****************************************************/
__swi(0x00) void SwiHandle1(int Handle);

#define IRQDisable() SwiHandle1(0)
#define IRQEnable()SwiHandle1(1)
#define FIQDisable() SwiHandle1(2)
#define FIQEnable()SwiHandle1(3)
/***********************************************备注****************************************************
**使用SWI软件中断跳出用户模式,进入特权模式访问CPSR
**相应代码存放在启动代码Startup.s中SWI软件中服务函数块
*******************************************************************************************


只要调用,IRQDisable()IRQEnable()FIQDisable() FIQEnable() 就行

ksniper 发表于 2010-5-29 08:34:22

mark

liangyurongde 发表于 2010-5-29 12:17:15

mark

xlsbz 发表于 2010-5-31 19:20:17

弄了两天得出结论 :我比较菜!等以后再说吧

C中嵌入汇编

不断改汇编 结果不断进入各种进去abort Pabort Dabort undef

xlsbz 发表于 2010-5-31 19:37:27

回复【3楼】tangwei039
-----------------------------------------------------------------------

好1!!

不过我用的是CARM编译器 你的代码还不能直接用不过给我提供了思路 多谢

dr2001 发表于 2010-5-31 20:09:18

除非必要,尽量少动汇编。

如果是裸奔或者对权限不敏感的应用,就不要切User模式了,直接在SYS下跑挺好的。

xlsbz 发表于 2010-5-31 20:20:49

回复【8楼】dr2001
-----------------------------------------------------------------------

请问有什么证据?

多谢!

官方有说明么?

dr2001 发表于 2010-5-31 20:38:00

需要什么证据?你自己的工程,你自己的代码,你自己管理一切。爱怎么用就怎么用。即便是移植个OS,这些事儿也是听你的。

少用汇编让代码容易维护。精心调整过的汇编,你过两个月一般不会一眼就看明白什么地方在干什么,但C语言不至于这么惨。

处理器模式和堆栈维护全凭个人爱好和代码需求。如果你的工程能完全由你做主,确定其操作。
那么,USR不能干的事情,用SVC模式打个洞让他都能完成了,和在SYS直接跑有什么区别?

裸奔的代码,较真就错了。
因为Coder掌控一切,Coder觉得爽,就已经是真的爽了。

xlsbz 发表于 2010-5-31 21:51:29

回复【10楼】dr2001
-----------------------------------------------------------------------

没有理由不行啊

不是闹着玩的!

dr2001 发表于 2010-6-1 11:36:03

如果你认为目前的处理器模式,堆栈分配,让你觉得十分清晰高效,应用便是。
别人说的都是建议,但不会没事儿干给你提建议闹着玩。

最终程序肯定要执行在SYS/USR二者之一,否则只要进异常,LR就被打掉,潜在导致程序流程的问题。
当然,你的设计要是兼容这些情况,即便用户代码跑在IRQ模式也没任何问题。

要不要特权,若干模式下堆栈怎么设计,如何管理,这是各个裸奔应用/OS考虑的问题,各有个的方法。没有标准答案。

xlsbz 发表于 2010-6-1 18:10:42

回复【12楼】dr2001
-----------------------------------------------------------------------

楼上看样子是强人 多谢!

我一直不太明白 SYS和USR区别在哪里?
我就知道SYS是特权模式,USR不是特权模式。

还有什么区别么?

dr2001 发表于 2010-6-1 19:49:53

除特权操作能否执行外,USR与SYS无区别。

anigon 发表于 2010-8-6 09:09:49

mark
页: [1]
查看完整版本: 关于如何禁止、启动IRQ FIQ?