How to know if all interrupts are disabled or not Kinetis KL1x

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

How to know if all interrupts are disabled or not Kinetis KL1x

跳至解决方案
5,043 次查看
sys
Contributor III

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

标签 (1)
0 项奖励
回复
1 解答
4,438 次查看
sys
Contributor III

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

在原帖中查看解决方案

10 回复数
4,439 次查看
sys
Contributor III

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

4,438 次查看
bobpaddock
Senior Contributor III

The code I posted *IS* atomic.h.  It shows how to read the current state of the IRQs and restore them to that state.

4,440 次查看
sys
Contributor III

Ops!! Sorry Bob I didnt understand this :smileyblush:

I thinked it was a in-bundle module just present in the KSDK... :smileyhappy:

thanks anyway Bob for help, u gave me good suggestions!

Sandro

0 项奖励
回复
4,440 次查看
bobpaddock
Senior Contributor III

Think of atomic.h as the bare-metal version.

4,440 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport

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

0 项奖励
回复
4,440 次查看
sys
Contributor III

Mmm I dont know Bob :-)

Anyway, you could put in bold-mode the lines that could be useful for me...in fact I cant understand where is the solution for me... :smileyhappy:

Thanks!

Sandro

0 项奖励
回复
4,440 次查看
bobpaddock
Senior Contributor III

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. :-(

4,440 次查看
bobpaddock
Senior Contributor III

/** @(#)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 */

0 项奖励
回复
4,440 次查看
bobpaddock
Senior Contributor III

What is the correct way to have this system include code?  It looks fine to me when I enter it and then looks like garbage when it is posted. :-(

0 项奖励
回复
4,440 次查看
bobpaddock
Senior Contributor III

<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 */ 
0 项奖励
回复