查看EFM32的源代码
←
EFM32
跳转到:
导航
,
搜索
因为以下原因,你没有权限编辑本页:
您刚才请求的操作只有这个用户组中的用户才能使用:
用户
您可以查看并复制此页面的源代码:
== Interrupt == '''NOTE:''' 中断处理函数中不可有太多消耗内存栈的操作(尤其 Serial.print() 这类字符输出函数调用),多次嵌套中断(比如用镊子触发FALLING)极其容易造成栈溢出。。。 === Register === * primask <br><br> === API === Interrupts() and noInterrupts(): (本质都是直接设置 primask 这个寄存器) <source lang=cpp> /* * Enables IRQ interrupts by clearing the I-bit in the CPSR. * Can only be executed in Privileged modes. */ __attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) { __ASM volatile ("cpsie i" : : : "memory"); } /* * Disables IRQ interrupts by setting the I-bit in the CPSR. * Can only be executed in Privileged modes. */ __attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) { __ASM volatile ("cpsid i" : : : "memory"); } </source> Suggest to use: (@ emlib/src/em_core.c or inc/em_core.h) <source lang=cpp> CORE_DECLARE_IRQ_STATE; CORE_ENTER_CRITICAL(); your_code CORE_EXIT_CRITICAL() ; or: CORE_DECLARE_IRQ_STATE; CORE_ENTER_ATOMIC(); your_code CORE_EXIT_ATOMIC(); </source> <b>CRITICAL</b> section: Inside a critical sections all interrupts are disabled (except for fault handlers). The PRIMASK register is always used for interrupt disable/enable. <b>ATOMIC</b> section: This type of section is configurable and the default method is to use PRIMASK. With BASEPRI configuration, interrupts with priority equal to or lower than a given configurable level are disabled. The interrupt disable priority level is defined at compile time. The BASEPRI register is not available for all architectures. <b>NVIC mask</b> section: Disable NVIC (external interrupts) on an individual manner. '''获取 primask 寄存器的值并保存之:''' <source lang=cpp> /* * Returns the current state of the priority mask bit from the Priority Mask Register. * Priority Mask value */ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) { uint32_t result; __ASM volatile ("MRS %0, primask" : "=r" (result) ); return(result); } </source> The exception mask register PRIMASK, that is used for priority boosting. PRIMASK is a special-purpose mask register. <br> === Interrupt Vector === arch/efm32/sys/SiliconLabs/EFM32ZG/Source/GCC/startup_efm32zg.S: <source lang=cpp> .section .vectors .align 2 .globl __Vectors __Vectors: .long __StackTop /* Top of Stack */ .long Reset_Handler /* Reset Handler */ .long NMI_Handler /* NMI Handler */ .long HardFault_Handler /* Hard Fault Handler */ .long Default_Handler /* Reserved */ .long Default_Handler /* Reserved */ .long Default_Handler /* Reserved */ .long Default_Handler /* Reserved */ .long Default_Handler /* Reserved */ .long Default_Handler /* Reserved */ .long Default_Handler /* Reserved */ .long SVC_Handler /* SVCall Handler */ .long Default_Handler /* Reserved */ .long Default_Handler /* Reserved */ .long PendSV_Handler /* PendSV Handler */ .long SysTick_Handler /* SysTick Handler */ /* External interrupts */ .long DMA_IRQHandler /* 0 - DMA */ .long GPIO_EVEN_IRQHandler /* 1 - GPIO_EVEN */ .long TIMER0_IRQHandler /* 2 - TIMER0 */ .long ACMP0_IRQHandler /* 3 - ACMP0 */ .long ADC0_IRQHandler /* 4 - ADC0 */ .long I2C0_IRQHandler /* 5 - I2C0 */ .long GPIO_ODD_IRQHandler /* 6 - GPIO_ODD */ .long TIMER1_IRQHandler /* 7 - TIMER1 */ .long USART1_RX_IRQHandler /* 8 - USART1_RX */ .long USART1_TX_IRQHandler /* 9 - USART1_TX */ .long LEUART0_IRQHandler /* 10 - LEUART0 */ .long PCNT0_IRQHandler /* 11 - PCNT0 */ .long RTC_IRQHandler /* 12 - RTC */ .long CMU_IRQHandler /* 13 - CMU */ .long VCMP_IRQHandler /* 14 - VCMP */ .long MSC_IRQHandler /* 15 - MSC */ .long AES_IRQHandler /* 16 - AES */ .long Default_Handler /* 17 - Reserved */ .long Default_Handler /* 18 - Reserved */ .size __Vectors, . - __Vectors .text .thumb .thumb_func .align 2 .globl Reset_Handler .type Reset_Handler, %function Reset_Handler: #ifndef __NO_SYSTEM_INIT ldr r0, =SystemInit blx r0 #endif </source> arch/efm32/sys/SiliconLabs/EFM32ZG/Source/GCC/startup_efm32zg.c: <source lang=cpp> const pFunc __Vectors[] __attribute__ ((section(".vectors"))) = { /* Cortex-M Exception Handlers */ (pFunc)&__StackTop, /* Initial Stack Pointer */ Reset_Handler, /* Reset Handler */ NMI_Handler, /* NMI Handler */ HardFault_Handler, /* Hard Fault Handler */ Default_Handler, /* Reserved */ Default_Handler, /* Reserved */ Default_Handler, /* Reserved */ Default_Handler, /* Reserved */ Default_Handler, /* Reserved */ Default_Handler, /* Reserved */ Default_Handler, /* Reserved */ SVC_Handler, /* SVCall Handler */ Default_Handler, /* Reserved */ Default_Handler, /* Reserved */ PendSV_Handler, /* PendSV Handler */ SysTick_Handler, /* SysTick Handler */ /* External interrupts */ DMA_IRQHandler, /* 0 - DMA */ GPIO_EVEN_IRQHandler, /* 1 - GPIO_EVEN */ TIMER0_IRQHandler, /* 2 - TIMER0 */ ACMP0_IRQHandler, /* 3 - ACMP0 */ ADC0_IRQHandler, /* 4 - ADC0 */ I2C0_IRQHandler, /* 5 - I2C0 */ GPIO_ODD_IRQHandler, /* 6 - GPIO_ODD */ TIMER1_IRQHandler, /* 7 - TIMER1 */ USART1_RX_IRQHandler, /* 8 - USART1_RX */ USART1_TX_IRQHandler, /* 9 - USART1_TX */ LEUART0_IRQHandler, /* 10 - LEUART0 */ PCNT0_IRQHandler, /* 11 - PCNT0 */ RTC_IRQHandler, /* 12 - RTC */ CMU_IRQHandler, /* 13 - CMU */ VCMP_IRQHandler, /* 14 - VCMP */ MSC_IRQHandler, /* 15 - MSC */ AES_IRQHandler, /* 16 - AES */ Default_Handler, /* 17 - Reserved */ Default_Handler, /* 18 - Reserved */ }; /*---------------------------------------------------------------------------- Reset Handler called on controller reset *----------------------------------------------------------------------------*/ void Reset_Handler(void) { ...... ...... </source> <br> === SysTick Interrupt === Here is how we configure the SysTick interrupt so that it is enabled and running at 1ms interrupts: <source lang=cpp> SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)); </source> * https://www.silabs.com/community/blog.entry.html/2015/06/29/chapter_5_mcu_clocki-pEjC <br>
返回到
EFM32
。
个人工具
登录
名字空间
页面
讨论
变换
查看
阅读
查看源代码
查看历史
操作
搜索
导航
首页
社区专页
新闻动态
最近更改
随机页面
帮助
工具箱
链入页面
相关更改
特殊页面