Skip to content

Commit b1277d1

Browse files
committed
CO_driver_target.h: Add FreeRTOS locking example
- Code can be enabled by enabling the USE_FREERTOS_LOCKING preprocessor symbol in the build config.
1 parent 0897c74 commit b1277d1

1 file changed

Lines changed: 52 additions & 0 deletions

File tree

CANopenNode_STM32/CO_driver_target.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@
3535
#include <stddef.h>
3636
#include <stdint.h>
3737

38+
#ifdef USE_FREERTOS_LOCKING
39+
#include "FreeRTOS.h"
40+
#include "task.h"
41+
#endif
42+
3843
// Determining the CANOpen Driver
3944

4045
#if defined(FDCAN) || defined(FDCAN1) || defined(FDCAN2) || defined(FDCAN3)
@@ -137,6 +142,52 @@ typedef struct {
137142
} CO_storage_entry_t;
138143

139144
/* (un)lock critical section in CO_CANsend() */
145+
#ifdef USE_FREERTOS_LOCKING
146+
147+
// NOTE: valid for STM32F3XX. Not tested on other MCUs
148+
// This works as long as you don't have interrupts pre-empting each other, which call the CO_LOCK_* macros below!
149+
#define CO_VECTACTIVE_MASK (0xFFUL)
150+
#define CO_IS_IRQ() ((portNVIC_INT_CTRL_REG & CO_VECTACTIVE_MASK) != 0)
151+
152+
#define CO_ENTER_CRITICAL_SECTION() \
153+
do \
154+
{ \
155+
if (CO_IS_IRQ()) \
156+
{ \
157+
taskENTER_CRITICAL_FROM_ISR(); \
158+
} \
159+
else \
160+
{ \
161+
taskENTER_CRITICAL(); \
162+
} \
163+
} while (0)
164+
165+
#define CO_EXIT_CRITICAL_SECTION() \
166+
do \
167+
{ \
168+
if (CO_IS_IRQ()) \
169+
{ \
170+
taskEXIT_CRITICAL_FROM_ISR(0); \
171+
} \
172+
else \
173+
{ \
174+
taskEXIT_CRITICAL(); \
175+
} \
176+
} while (0)
177+
178+
/* (un)lock critical section in CO_CANsend() */
179+
#define CO_LOCK_CAN_SEND(CAN_MODULE) CO_ENTER_CRITICAL_SECTION()
180+
#define CO_UNLOCK_CAN_SEND(CAN_MODULE) CO_EXIT_CRITICAL_SECTION()
181+
182+
/* (un)lock critical section when accessing Object Dictionary */
183+
#define CO_LOCK_OD(CAN_MODULE) CO_ENTER_CRITICAL_SECTION()
184+
#define CO_UNLOCK_OD(CAN_MODULE) CO_EXIT_CRITICAL_SECTION()
185+
186+
/* (un)lock critical section in CO_errorReport() or CO_errorReset() */
187+
#define CO_LOCK_EMCY(CAN_MODULE) CO_ENTER_CRITICAL_SECTION()
188+
#define CO_UNLOCK_EMCY(CAN_MODULE) CO_EXIT_CRITICAL_SECTION()
189+
190+
#else
140191
// Why disabling the whole Interrupt
141192
#define CO_LOCK_CAN_SEND(CAN_MODULE) \
142193
do { \
@@ -160,6 +211,7 @@ typedef struct {
160211
__disable_irq(); \
161212
} while (0)
162213
#define CO_UNLOCK_OD(CAN_MODULE) __set_PRIMASK((CAN_MODULE)->primask_od)
214+
#endif
163215

164216
/* Synchronization between CAN receive and message processing threads. */
165217
#define CO_MemoryBarrier()

0 commit comments

Comments
 (0)