开关中断与cpsid/cpsie指令

在汇编代码中,CPSID   CPSIE  用于快速的开关中断。

CPSID

I

;PRIMASK=1,

;关中断

CPSIE

I

;PRIMASK=0,

;开中断

CPSID 

CPSIE

F

F

;FAULTMASK=1,

;FAULTMASK=0

;关异常

;开异常


I:IRQ中断;    F:FIQ中断

最常见的这两个命令的使用处是在关中断、开中断的实现中,我们经常用的local_irq_save和local_irq_restore最终都是调用了以下两个实现,即关/开中断只是操作了CPSR中的中断标志位而已,并没有去对GIC做操作,只是简单的不让CPU响应中断,具体实现在arch/arm/include/asm/irqflags.h文件中。

static inline void arch_local_irq_enable(void)
{
	asm volatile(
		"	cpsie i			@ arch_local_irq_enable"
		:
		:
		: "memory", "cc");
}
static inline void arch_local_irq_disable(void)
{
	asm volatile(
		"	cpsid i			@ arch_local_irq_disable"
		:
		:
		: "memory", "cc");
}
#define local_fiq_enable()  __asm__("cpsie f	@ __stf" : : : "memory", "cc")
#define local_fiq_disable() __asm__("cpsid f	@ __clf" : : : "memory", "cc")
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
不超过100行的FReeRTOS,只有核心代码。只适合转牛角尖者,研究FReeRTOS原理者。 #include "task.h" #include "usart.h" TCB *TCBCur; u32 Prio_t = 0; TCB TCBL[64]; void task_create(void (* task)(void ),u32 *STK,u32 prio) { TCBCur = &TCBL;[prio]; *(--STK) = 1<<24; *(--STK) = ( u32 ) task; TCBL[prio].stkPtr = STK-14; } void CtxSw( void ) { TCBCur = &TCBL;[ Prio_t ]; } u8 STK_SizeChk(u32 *STK) { u32 i=0; while(!*STK++)i++; return i; } __asm void OSstart( void ) { extern TCBCur; PRESERVE8 ldr r3, =TCBCur /* Obtain location of TCBCur. */ ldr r1, [r3] ldr r0, [r1] /* The first item in TCBCur is the task top of stack. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ movs r0, #2 /* Switch to the psp stack. */ msr CONTROL, r0 pop {r0-r5} /* Pop the registers that are saved automatically. */ mov lr, r5 /* lr is now in r5. */ cpsie i /* The first task has its context and interrupts can be enabled. */ pop {pc} /* Finally, pop the PC to jump to the user defined task code. */ ALIGN } __asm void PendSV_Handler( void ) { extern CtxSw extern TCBCur PRESERVE8 mrs r0, psp ldr r3, =TCBCur /* Get the location of the current TCB. */ ldr r2, [r3] subs r0, #32 /* Make space for the remaining low registers. */ str r0, [r2] /* Save the new top of stack. */ stmia r0!, {r4-r7} /* Store the low registers that are not saved automatically. */ mov r4, r8 /* Store the high registers. */ mov r5, r9 mov r6, r10 mov r7, r11 stmia r0!, {r4-r7} push {r3, r14} cpsid i bl CtxSw cpsie i pop {r2, r3} /* lr goes in r3. r2 now holds tcb pointer. */ ldr r1, [r2] ldr r0, [r1] /* The first item in TCBCur is the task top of stack. */ adds r0, #16 /* Move to the high registers. */ ldmia r0!, {r4-r7} /* Pop the high registers. */ mov r8, r4 mov r9, r5 mov r10, r6 mov r11, r7 msr psp, r0 /* Remember the new top of stack for the task. */ subs r0, #32 /* Go back for the low registers that are not automatically restored. */ ldmia r0!, {r4-r7} /* Pop low registers. */ bx r3 ALIGN }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值