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

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

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

Jump to solution
2,613 Views
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

Labels (1)
0 Kudos
1 Solution
2,008 Views
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

View solution in original post

10 Replies
2,009 Views
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

2,008 Views
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.

2,010 Views
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 Kudos
2,010 Views
bobpaddock
Senior Contributor III

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

2,010 Views
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 Kudos
2,010 Views
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 Kudos
2,010 Views
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. :-(

2,010 Views
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 Kudos
2,010 Views
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 Kudos
2,010 Views
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 Kudos