Advertisement
Guest User

Atomic sections for ARM

a guest
Oct 28th, 2015
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.07 KB | None | 0 0
  1. /** @(#)atomic.h     <18-Aug-2014 13:31:09 bob p>
  2.  *  Last Time-stamp: <03-Sep-2015 13:17:44 bob p>
  3.  *
  4.  *  \file atomic.h
  5.  *  \brief  Port of Dean Camera's ATOMIC_BLOCK macros for AVR to ARM Cortex M3.
  6.  *
  7.  */
  8.  
  9. /*lint -save -e755 -e756 Disable warning(s), this file only, global macro/typedef 'Symbol' (Location) not referenced */
  10.  
  11. #ifndef _ATOMIC_H_
  12. #define _ATOMIC_H_ (1)
  13.  
  14. #ifdef  DEFINE_SPACE_ATOMIC_H
  15. #define EXTERN_ATOMIC
  16. #else
  17. #define EXTERN_ATOMIC extern
  18. #endif
  19.  
  20. #if defined(__cplusplus) && __cplusplus
  21.  extern "C" {
  22. #endif
  23.  
  24. /*
  25. * This is port of Dean Camera's ATOMIC_BLOCK macros for AVR to ARM Cortex M3
  26. * v1.0
  27. * Mark Pendrith, Nov 27, 2012.
  28. *
  29. * From Mark:
  30. * >When I ported the macros I emailed Dean to ask what attribution would be
  31. * >appropriate, and here is his response:
  32. * >
  33. * >>Mark,
  34. * >>I think it's great that you've ported the macros; consider them
  35. * >>public domain, to do with whatever you wish. I hope you find them >useful .
  36. * >>
  37. * >>Cheers!
  38. * >>- Dean
  39. */
  40.  
  41. #ifdef __arm__
  42. #ifndef _CORTEX_M3_ATOMIC_H_
  43. #define _CORTEX_M3_ATOMIC_H_
  44.  
  45. static __inline__ uint32_t __get_primask(void) \
  46. { uint32_t primask = 0; \
  47.   __asm__ volatile ("MRS %[result], PRIMASK\n\t":[result]"=r"(primask)::); \
  48.   return primask; } // returns 0 if interrupts enabled, 1 if disabled
  49.  
  50. static __inline__ void __set_primask(uint32_t setval) \
  51. { __asm__ volatile ("MSR PRIMASK, %[value]\n\t""dmb\n\t""dsb\n\t""isb\n\t"::[value]"r"(setval):);
  52.   __asm__ volatile ("" ::: "memory");}
  53.  
  54. static __inline__ uint32_t __iSeiRetVal(void) \
  55. { __asm__ volatile ("CPSIE i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \
  56.   __asm__ volatile ("" ::: "memory"); return 1; }
  57.  
  58. static __inline__ uint32_t __iCliRetVal(void) \
  59. { __asm__ volatile ("CPSID i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \
  60.   __asm__ volatile ("" ::: "memory"); return 1; }
  61.  
  62. static __inline__ void    __iSeiParam(const uint32_t *__s) \
  63. { __asm__ volatile ("CPSIE i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \
  64.   __asm__ volatile ("" ::: "memory"); (void)__s; }
  65.  
  66. static __inline__ void    __iCliParam(const uint32_t *__s) \
  67. { __asm__ volatile ("CPSID i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \
  68.   __asm__ volatile ("" ::: "memory"); (void)__s; }
  69.  
  70. static __inline__ void    __iRestore(const  uint32_t *__s) \
  71. { __set_primask(*__s); __asm__ volatile ("dmb\n\t""dsb\n\t""isb\n\t"); \
  72.   __asm__ volatile ("" ::: "memory"); }
  73.  
  74.  
  75. #define ATOMIC_BLOCK(type) \
  76. for ( type, __ToDo = __iCliRetVal(); __ToDo ; __ToDo = 0 )
  77.  
  78. #define ATOMIC_RESTORESTATE \
  79. uint32_t primask_save __attribute__((__cleanup__(__iRestore)))  = __get_primask()
  80.  
  81. #define ATOMIC_FORCEON \
  82. uint32_t primask_save __attribute__((__cleanup__(__iSeiParam))) = 0
  83.  
  84. #define NONATOMIC_BLOCK(type) \
  85. for ( type, __ToDo = __iSeiRetVal(); __ToDo ;  __ToDo = 0 )
  86.  
  87. #define NONATOMIC_RESTORESTATE \
  88. uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask()
  89.  
  90. #define NONATOMIC_FORCEOFF \
  91. uint32_t primask_save __attribute__((__cleanup__(__iCliParam))) = 0
  92.  
  93. #endif
  94. #endif
  95.  
  96. #if defined(__cplusplus) && __cplusplus
  97.  }
  98. #endif
  99.  
  100. #endif /* _ATOMIC_H_ */
  101.  
  102. /*lint -restore */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement