Hi all,
On MKL17Z I use "OSA_EnterCritical(kCriticalDisableInt)" and "OSA_ExitCritical(kCriticalDisableInt)" to disable/enable interrupts, and all seems to work fine.
My question is: is there a way to READ/GET the status of interrupts enabling? At the end to know if I am in a Critical section or not.
Thanks in advance!
Sandro
已解决! 转到解答。
Thanks for answer Bob,
unfortunately I dont have the atomic.h module...
Anyway, no problem! I solved in this way:
First of all, my necessity was to be sure that calling a function from other one, wont enable by mistake the interrupts, while the calling function "thinks" that interrupts are still disabled. Example in pseudo-code:
void F1(void) {
....
DISABLE_INTERRUPT
....
F2();
....
....
ENABLE_INTERRUPT
}
void F2(void) {
...
DISABLE_INTERRUPT
....
.....
.....
ENABLE_INTERRUPT
}
As u simply can understand, the instructions after the F2 call, would be with interrupt enabled! That's why I would have need a way to check interrupts state.
Luckly, the KSDK (1.2.0) provided for MKL17Z and KDS 3.0.0, provide 2 primitives OSA_EnterCritical and OSA_ExitCritical (from fsl_os_abstraction component), that manage this automatically, with counters that keep in mind how many time interrupts disable request is called. I didnt notice this before create this discussion.
So u can call nested disable request without problem.
Hope this can help someone :-)
Thanks againg Bob.
Sandro
Thanks for answer Bob,
unfortunately I dont have the atomic.h module...
Anyway, no problem! I solved in this way:
First of all, my necessity was to be sure that calling a function from other one, wont enable by mistake the interrupts, while the calling function "thinks" that interrupts are still disabled. Example in pseudo-code:
void F1(void) {
....
DISABLE_INTERRUPT
....
F2();
....
....
ENABLE_INTERRUPT
}
void F2(void) {
...
DISABLE_INTERRUPT
....
.....
.....
ENABLE_INTERRUPT
}
As u simply can understand, the instructions after the F2 call, would be with interrupt enabled! That's why I would have need a way to check interrupts state.
Luckly, the KSDK (1.2.0) provided for MKL17Z and KDS 3.0.0, provide 2 primitives OSA_EnterCritical and OSA_ExitCritical (from fsl_os_abstraction component), that manage this automatically, with counters that keep in mind how many time interrupts disable request is called. I didnt notice this before create this discussion.
So u can call nested disable request without problem.
Hope this can help someone :-)
Thanks againg Bob.
Sandro
Hi, Bob,
It seems that you are talking how to check if the interrupt is enabled or disabled. I think you can check the PRIMASK register at least in debugger of tools.
CPSID i ; Disable interrupts and configurable fault handlers (set last bit of PRIMASK)
CPSIE i ; Enable interrupts and configurable fault handlers (clear last bit of PRIMASK)
If you do not talk about how to check the interrupt, pls ignore it.
BR
XiangJun Rong
Yes the solution was for you. Shows how to do atomic sections of code. Automatically saves the current interrupt state and restores it. Use it like this:
#include "atomic.h"
ATOMIC_BLOCK( ATOMIC_RESTORESTATE )
{
/* Your code that needs IRQs off goes here */
}/* ATOMIC_BLOCK( ATOMIC_RESTORESTATE ) */
[C] Atomic sections for ARM - Pastebin.com
I put the code on pastebin until someone can tell me the magic word to past or attach code. Best I can tell the site is browser specific or I need some App I don't have from the Jive App Market. :-(
/** @(#)atomic.h * Last Time-stamp: * * \file atomic.h * \brief Port of Dean Camera's ATOMIC_BLOCK macros for AVR to ARM Cortex M3. * */ /*lint -save -e755 -e756 Disable warning(s), this file only, global macro/typedef 'Symbol' (Location) not referenced */ #ifndef _ATOMIC_H_ #define _ATOMIC_H_ (1) #ifdef DEFINE_SPACE_ATOMIC_H #define EXTERN_ATOMIC #else #define EXTERN_ATOMIC extern #endif #if defined(__cplusplus) && __cplusplus extern "C" { #endif /* * This is port of Dean Camera's ATOMIC_BLOCK macros for AVR to ARM Cortex M3 * v1.0 * Mark Pendrith, Nov 27, 2012. * * From Mark: * >When I ported the macros I emailed Dean to ask what attribution would be * >appropriate, and here is his response: * >* >>Mark, * >>I think it's great that you've ported the macros; consider them * >>public domain, to do with whatever you wish. I hope you find them >useful . * >>* >>Cheers! * >>- Dean */ #ifdef __arm__ #ifndef _CORTEX_M3_ATOMIC_H_ #define _CORTEX_M3_ATOMIC_H_ static __inline__ uint32_t __get_primask(void) \ { uint32_t primask = 0; \ __asm__ volatile ("MRS %[result], PRIMASK\n\t":[result]"=r"(primask)::); \ return primask; } // returns 0 if interrupts enabled, 1 if disabled static __inline__ void __set_primask(uint32_t setval) \ { __asm__ volatile ("MSR PRIMASK, %[value]\n\t""dmb\n\t""dsb\n\t""isb\n\t"::[value]"r"(setval):); __asm__ volatile ("" ::: "memory");} static __inline__ uint32_t __iSeiRetVal(void) \ { __asm__ volatile ("CPSIE i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ __asm__ volatile ("" ::: "memory"); return 1; } static __inline__ uint32_t __iCliRetVal(void) \ { __asm__ volatile ("CPSID i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ __asm__ volatile ("" ::: "memory"); return 1; } static __inline__ void __iSeiParam(const uint32_t *__s) \ { __asm__ volatile ("CPSIE i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ __asm__ volatile ("" ::: "memory"); (void)__s; } static __inline__ void __iCliParam(const uint32_t *__s) \ { __asm__ volatile ("CPSID i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ __asm__ volatile ("" ::: "memory"); (void)__s; } static __inline__ void __iRestore(const uint32_t *__s) \ { __set_primask(*__s); __asm__ volatile ("dmb\n\t""dsb\n\t""isb\n\t"); \ __asm__ volatile ("" ::: "memory"); } #define ATOMIC_BLOCK(type) \ for ( type, __ToDo = __iCliRetVal(); __ToDo ; __ToDo = 0 ) #define ATOMIC_RESTORESTATE \ uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask() #define ATOMIC_FORCEON \ uint32_t primask_save __attribute__((__cleanup__(__iSeiParam))) = 0 #define NONATOMIC_BLOCK(type) \ for ( type, __ToDo = __iSeiRetVal(); __ToDo ; __ToDo = 0 ) #define NONATOMIC_RESTORESTATE \ uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask() #define NONATOMIC_FORCEOFF \ uint32_t primask_save __attribute__((__cleanup__(__iCliParam))) = 0 #endif #endif #if defined(__cplusplus) && __cplusplus } #endif #endif /* _ATOMIC_H_ */ /*lint -restore */
<atomic.h> was originally written for the AVR it has been ported to the ARM:
/** @(#)atomic.h * Last Time-stamp: * * \file atomic.h * \brief Port of Dean Camera's ATOMIC_BLOCK macros for AVR to ARM Cortex M3. * */ /*lint -save -e755 -e756 Disable warning(s), this file only, global macro/typedef 'Symbol' (Location) not referenced */ #ifndef _ATOMIC_H_ #define _ATOMIC_H_ (1) #ifdef DEFINE_SPACE_ATOMIC_H #define EXTERN_ATOMIC #else #define EXTERN_ATOMIC extern #endif #if defined(__cplusplus) && __cplusplus extern "C" { #endif /* * This is port of Dean Camera's ATOMIC_BLOCK macros for AVR to ARM Cortex M3 * v1.0 * Mark Pendrith, Nov 27, 2012. * * From Mark: * >When I ported the macros I emailed Dean to ask what attribution would be * >appropriate, and here is his response: * >* >>Mark, * >>I think it's great that you've ported the macros; consider them * >>public domain, to do with whatever you wish. I hope you find them >useful . * >>* >>Cheers! * >>- Dean */ #ifdef __arm__ #ifndef _CORTEX_M3_ATOMIC_H_ #define _CORTEX_M3_ATOMIC_H_ static __inline__ uint32_t __get_primask(void) \ { uint32_t primask = 0; \ __asm__ volatile ("MRS %[result], PRIMASK\n\t":[result]"=r"(primask)::); \ return primask; } // returns 0 if interrupts enabled, 1 if disabled static __inline__ void __set_primask(uint32_t setval) \ { __asm__ volatile ("MSR PRIMASK, %[value]\n\t""dmb\n\t""dsb\n\t""isb\n\t"::[value]"r"(setval):); __asm__ volatile ("" ::: "memory");} static __inline__ uint32_t __iSeiRetVal(void) \ { __asm__ volatile ("CPSIE i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ __asm__ volatile ("" ::: "memory"); return 1; } static __inline__ uint32_t __iCliRetVal(void) \ { __asm__ volatile ("CPSID i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ __asm__ volatile ("" ::: "memory"); return 1; } static __inline__ void __iSeiParam(const uint32_t *__s) \ { __asm__ volatile ("CPSIE i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ __asm__ volatile ("" ::: "memory"); (void)__s; } static __inline__ void __iCliParam(const uint32_t *__s) \ { __asm__ volatile ("CPSID i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ __asm__ volatile ("" ::: "memory"); (void)__s; } static __inline__ void __iRestore(const uint32_t *__s) \ { __set_primask(*__s); __asm__ volatile ("dmb\n\t""dsb\n\t""isb\n\t"); \ __asm__ volatile ("" ::: "memory"); } #define ATOMIC_BLOCK(type) \ for ( type, __ToDo = __iCliRetVal(); __ToDo ; __ToDo = 0 ) #define ATOMIC_RESTORESTATE \ uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask() #define ATOMIC_FORCEON \ uint32_t primask_save __attribute__((__cleanup__(__iSeiParam))) = 0 #define NONATOMIC_BLOCK(type) \ for ( type, __ToDo = __iSeiRetVal(); __ToDo ; __ToDo = 0 ) #define NONATOMIC_RESTORESTATE \ uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask() #define NONATOMIC_FORCEOFF \ uint32_t primask_save __attribute__((__cleanup__(__iCliParam))) = 0 #endif #endif #if defined(__cplusplus) && __cplusplus } #endif #endif /* _ATOMIC_H_ */ /*lint -restore */