foxBMS  1.6.0
The foxBMS Battery Management System API Documentation
os_freertos.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2023, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file os_freertos.c
44  * @author foxBMS Team
45  * @date 2021-11-18 (date of creation)
46  * @updated 2023-10-12 (date of last update)
47  * @version v1.6.0
48  * @ingroup OS
49  * @prefix OS
50  *
51  * @brief FreeRTOS specific implementation of the tasks and resources used by
52  * the system
53  */
54 
55 /*========== Includes =======================================================*/
56 #include "os.h"
57 
58 #include "HL_sys_core.h"
59 
60 #include "can_cbs_tx_crash-dump.h"
61 #include "ftask.h"
62 
63 #include <stdint.h>
64 
65 /*========== Macros and Definitions =========================================*/
66 
67 /*========== Static Constant and Variable Definitions =======================*/
68 
69 /*========== Extern Constant and Variable Definitions =======================*/
70 
71 /*========== Static Function Prototypes =====================================*/
72 
73 /*========== Static Function Implementations ================================*/
74 
75 /*========== Extern Function Implementations ================================*/
76 extern void OS_InitializeScheduler(void) {
77  if (OS_ENABLE_CACHE == true) {
78  _cacheEnable_();
79  }
80 }
81 
82 void OS_StartScheduler(void) {
83  vTaskStartScheduler();
84  /* This function should never return */
86 }
87 
89  StaticTask_t **ppxIdleTaskTCBBuffer,
90  StackType_t **ppxIdleTaskStackBuffer,
91  uint32_t *pulIdleTaskStackSize) {
92  /** Buffer for the Idle Task's structure */
93  static StaticTask_t os_idleTask = {0};
94  /** @brief Stack for the Idle task */
95  static StackType_t os_stackSizeIdle[OS_IDLE_TASK_STACK_SIZE] = {0};
96  FAS_ASSERT(ppxIdleTaskTCBBuffer != NULL_PTR);
97  FAS_ASSERT(ppxIdleTaskStackBuffer != NULL_PTR);
98  FAS_ASSERT(pulIdleTaskStackSize != NULL_PTR);
99  *ppxIdleTaskTCBBuffer = &os_idleTask;
100  *ppxIdleTaskStackBuffer = &os_stackSizeIdle[0];
101  *pulIdleTaskStackSize = OS_IDLE_TASK_STACK_SIZE;
102 }
103 
104 #if (configUSE_TIMERS > 0) && (configSUPPORT_STATIC_ALLOCATION == 1)
105 void vApplicationGetTimerTaskMemory(
106  StaticTask_t **ppxTimerTaskTCBBuffer,
107  StackType_t **ppxTimerTaskStackBuffer,
108  uint32_t *pulTimerTaskStackSize) {
109 #if (configUSE_TIMERS > 0) && (configSUPPORT_STATIC_ALLOCATION == 1)
110  /** Buffer for the Timer Task's structure */
111  static StaticTask_t os_timerTask;
112 #endif /* configUSE_TIMERS */
113 
114 #if (configUSE_TIMERS > 0) && (configSUPPORT_STATIC_ALLOCATION == 1)
115  /** Stack for the Timer Task */
116  static StackType_t os_stackSizeTimer[OS_TIMER_TASK_STACK_SIZE];
117 #endif /* configUSE_TIMERS */
118  *ppxTimerTaskTCBBuffer = &os_timerTask;
119  *ppxTimerTaskStackBuffer = &os_stackSizeTimer[0];
120  *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
121 }
122 #endif /* configUSE_TIMERS */
123 
126 }
127 
128 #if (configCHECK_FOR_STACK_OVERFLOW > 0)
129 /* FreeRTOS internal function, keep FreeRTOS types */
130 /* AXIVION Next Codeline Style CodingStyle-Naming.Function: keep the parameter
131  names as provided by FreeRTOS */
132 /* AXIVION Next Codeline Style MisraC2012-2.7: The parameters are only required
133  by the API given through FreeRTOS and are not used (as they are not needed),
134  therefore it is save to ignore them. */
135 /* AXIVION Next Codeline Style MisraC2012-8.13: The types of the parameters are
136  provided by the API. As stated, the parameters are not used, therefore the
137  'const'-qualifier can be ignored. */
138 /* AXIVION Next Codeline Style Generic-MissingParameterAssert: As stated above,
139  the parameters are not used, so there is no reason to assert their on their
140  values.*/
141 void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) {
142  /* After the FreeRTOS stack overflow detection has been triggered, try to
143  instantly send a CAN message, that tells the higher level control unit,
144  that a stack overflow appeared in one of the FreeRTOS tasks. */
147 }
148 #endif /* configCHECK_FOR_STACK_OVERFLOW */
149 
151  taskENTER_CRITICAL();
152 }
153 
155  taskEXIT_CRITICAL();
156 }
157 
158 uint32_t OS_GetTickCount(void) {
159  return xTaskGetTickCount(); /*TMS570 does not support nested interrupts*/
160 }
161 
162 void OS_DelayTaskUntil(uint32_t *pPreviousWakeTime, uint32_t milliseconds) {
163  FAS_ASSERT(pPreviousWakeTime != NULL_PTR);
164  FAS_ASSERT(milliseconds > 0u);
165  uint32_t ticks = (milliseconds / OS_TICK_RATE_MS);
166  if ((uint32_t)ticks < 1u) {
167  ticks = 1u; /* Minimum delay is 1 tick */
168  }
169  vTaskDelayUntil((TickType_t *)pPreviousWakeTime, (TickType_t)ticks);
170 }
171 
173  vPortTaskUsesFPU();
174 }
175 
176 extern OS_STD_RETURN_e OS_WaitForNotification(uint32_t *pNotifiedValue, uint32_t timeout) {
177  /* AXIVION Routine Generic-MissingParameterAssert: timeout: parameter accepts whole range */
178  FAS_ASSERT(pNotifiedValue != NULL_PTR);
179 
180  OS_STD_RETURN_e notificationReceived = OS_FAIL;
181  /* FreeRTOS: This function must not be used in an interrupt service routine. */
182  /* ulBitsToClearOnEntry and ulBitsToClearOnExit set to 0xffffffff
183  to clear all the bits in the task's notification value */
184  BaseType_t xNotificationReceived = xTaskNotifyWait(UINT32_MAX, UINT32_MAX, pNotifiedValue, timeout);
185  /* FreeRTOS:xTaskNotifyWait returns pdTRUE if notification was received (otherwise pdFALSE). */
186  if (xNotificationReceived == pdTRUE) {
187  notificationReceived = OS_SUCCESS;
188  }
189  return notificationReceived;
190 }
191 
192 extern OS_STD_RETURN_e OS_NotifyFromIsr(TaskHandle_t taskToNotify, uint32_t notifiedValue) {
193  /* AXIVION Routine Generic-MissingParameterAssert: notifiedValue: parameter accepts whole range */
194  FAS_ASSERT(taskToNotify != NULL_PTR);
195 
196  OS_STD_RETURN_e notification = OS_FAIL;
197  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
198  /* Return value dependent on the value of the eAction parameter, here set to eSetValueWithOverwrite */
199  BaseType_t xNotification =
200  xTaskNotifyFromISR(taskToNotify, notifiedValue, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
201  if (xNotification == pdTRUE) {
202  notification = OS_SUCCESS;
203  }
204  /* Make the scheduler yield when notification made, so that unblocked tasks is run immediately
205  (if priorities allow it, instead of waiting for the next OS tick) */
206  portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
207  return notification;
208 }
209 
211  uint32_t indexToWaitOn,
212  uint32_t *pNotifiedValue,
213  uint32_t timeout) {
214  /* AXIVION Routine Generic-MissingParameterAssert: timeout: parameter accepts whole range */
215  FAS_ASSERT(pNotifiedValue != NULL_PTR);
216 
217  OS_STD_RETURN_e notificationReceived = OS_FAIL;
218  /* FreeRTOS: This function must not be used in an interrupt service routine. */
219  /* ulBitsToClearOnEntry and ulBitsToClearOnExit set to 0xffffffff
220  to clear all the bits in the task's notification value */
221  BaseType_t xNotificationReceived =
222  xTaskNotifyWaitIndexed(indexToWaitOn, UINT32_MAX, UINT32_MAX, pNotifiedValue, timeout);
223  /* FreeRTOS:xTaskNotifyWait returns pdTRUE if notification was received (otherwise pdFALSE). */
224  if (xNotificationReceived == pdTRUE) {
225  notificationReceived = OS_SUCCESS;
226  }
227  return notificationReceived;
228 }
229 
231  TaskHandle_t taskToNotify,
232  uint32_t indexToNotify,
233  uint32_t notifiedValue) {
234  /* AXIVION Routine Generic-MissingParameterAssert: notifiedValue: parameter accepts whole range */
235  FAS_ASSERT(taskToNotify != NULL_PTR);
236 
237  OS_STD_RETURN_e notification = OS_FAIL;
238  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
239  /* Return value dependent on the value of the eAction parameter, here set to eSetValueWithOverwrite */
240  BaseType_t xNotification = xTaskNotifyIndexedFromISR(
241  taskToNotify, indexToNotify, notifiedValue, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
242  if (xNotification == pdTRUE) {
243  notification = OS_SUCCESS;
244  }
245  /* Make the scheduler yield when notification made, so that unblocked tasks is run immediately
246  (if priorities allow it, instead of waiting for the next OS tick) */
247  portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
248  return notification;
249 }
250 
251 extern OS_STD_RETURN_e OS_ClearNotificationIndexed(uint32_t indexToClear) {
252  /* AXIVION Routine Generic-MissingParameterAssert: indexToClear: parameter accepts whole range */
253 
254  OS_STD_RETURN_e notificationWasPending = OS_FAIL;
255  /* NULL passed for task handle: the clear is made for the calling task */
256  BaseType_t xNotificationWasPending = xTaskNotifyStateClearIndexed(NULL, indexToClear);
257  /* FreeRTOS:xTaskNotifyStateClearIndexed returns pdTRUE if a notification was pending (otherwise pdFALSE). */
258  if (xNotificationWasPending == pdTRUE) {
259  notificationWasPending = OS_SUCCESS;
260  }
261  return notificationWasPending;
262 }
263 
264 extern OS_STD_RETURN_e OS_ReceiveFromQueue(OS_QUEUE xQueue, void *const pvBuffer, uint32_t ticksToWait) {
265  FAS_ASSERT(pvBuffer != NULL_PTR);
266 
267  OS_STD_RETURN_e queueReceiveSuccessfully = OS_FAIL;
268  /* FreeRTOS: This function must not be used in an interrupt service routine. */
269  BaseType_t xQueueReceiveSuccess = xQueueReceive(xQueue, pvBuffer, (TickType_t)ticksToWait);
270  /* FreeRTOS:xQueueReceive returns pdTRUE if an item was successfully received from the queue (otherwise pdFALSE). */
271  if (xQueueReceiveSuccess == pdTRUE) {
272  queueReceiveSuccessfully = OS_SUCCESS;
273  }
274  return queueReceiveSuccessfully;
275 }
276 
277 extern OS_STD_RETURN_e OS_SendToBackOfQueue(OS_QUEUE xQueue, const void *const pvItemToQueue, uint32_t ticksToWait) {
278  FAS_ASSERT(pvItemToQueue != NULL_PTR);
279 
280  OS_STD_RETURN_e queueSendSuccessfully = OS_FAIL;
281  BaseType_t xQueueSendSuccess = xQueueSendToBack(xQueue, pvItemToQueue, (TickType_t)ticksToWait);
282  /* FreeRTOS:xQueueSendToBack returns pdTRUE if the item was successfully posted (otherwise errQUEUE_FULL). */
283  if (xQueueSendSuccess == pdTRUE) {
284  queueSendSuccessfully = OS_SUCCESS;
285  }
286  return queueSendSuccessfully;
287 }
288 
290  OS_QUEUE xQueue,
291  const void *const pvItemToQueue,
292  long *const pxHigherPriorityTaskWoken) {
293  FAS_ASSERT(pvItemToQueue != NULL_PTR);
294 
295  OS_STD_RETURN_e queueSendSuccessfully = OS_FAIL;
296  BaseType_t xQueueSendSuccess =
297  xQueueSendToBackFromISR(xQueue, pvItemToQueue, (BaseType_t *)pxHigherPriorityTaskWoken);
298  /* FreeRTOS:xQueueSendToBackFromISR returns pdTRUE if the item was successfully posted (otherwise errQUEUE_FULL). */
299  if (xQueueSendSuccess == pdTRUE) {
300  queueSendSuccessfully = OS_SUCCESS;
301  }
302  return queueSendSuccessfully;
303 }
304 
305 extern uint32_t OS_GetNumberOfStoredMessagesInQueue(OS_QUEUE xQueue) {
306  long numberOfMessages = uxQueueMessagesWaiting(xQueue);
307  return (uint32_t)numberOfMessages;
308 }
309 
310 /*========== Externalized Static Function Implementations (Unit Test) =======*/
311 #ifdef UNITY_UNIT_TEST
312 #endif
void CANTX_SendReasonsForFatalErrors(CANTX_FATAL_ERRORS_ACTIONS_e action)
Tries to send a CAN message in case of fatal error.
CAN Tx callback functions for transmitting information on fatal errors.
@ CANTX_FATAL_ERRORS_ACTIONS_STACK_OVERFLOW
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:255
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:129
#define NULL
NULL definition.
Definition: fstd_types.h:67
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
Header of task driver implementation.
void FTSK_RunUserCodeIdle(void)
Idle task.
Definition: ftask_cfg.c:308
Declaration of the OS wrapper interface.
OS_STD_RETURN_e
Definition: os.h:85
@ OS_SUCCESS
Definition: os.h:86
@ OS_FAIL
Definition: os.h:87
OS_STD_RETURN_e OS_NotifyFromIsr(TaskHandle_t taskToNotify, uint32_t notifiedValue)
Notify a task.
Definition: os_freertos.c:192
OS_STD_RETURN_e OS_WaitForNotification(uint32_t *pNotifiedValue, uint32_t timeout)
Wait for a notification.
Definition: os_freertos.c:176
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize)
Definition: os_freertos.c:88
OS_STD_RETURN_e OS_ClearNotificationIndexed(uint32_t indexToClear)
Clear pending notification of a task, with index.
Definition: os_freertos.c:251
OS_STD_RETURN_e OS_ReceiveFromQueue(OS_QUEUE xQueue, void *const pvBuffer, uint32_t ticksToWait)
Receive an item from a queue.
Definition: os_freertos.c:264
void OS_StartScheduler(void)
Starts the operating system scheduler.
Definition: os_freertos.c:82
void OS_DelayTaskUntil(uint32_t *pPreviousWakeTime, uint32_t milliseconds)
Delay a task until a specified time.
Definition: os_freertos.c:162
OS_STD_RETURN_e OS_SendToBackOfQueueFromIsr(OS_QUEUE xQueue, const void *const pvItemToQueue, long *const pxHigherPriorityTaskWoken)
Post an item to the back the provided queue during an ISR.
Definition: os_freertos.c:289
void OS_MarkTaskAsRequiringFpuContext(void)
Marks the current task as requiring FPU context.
Definition: os_freertos.c:172
uint32_t OS_GetNumberOfStoredMessagesInQueue(OS_QUEUE xQueue)
Check if messages are waiting for queue.
Definition: os_freertos.c:305
OS_STD_RETURN_e OS_WaitForNotificationIndexed(uint32_t indexToWaitOn, uint32_t *pNotifiedValue, uint32_t timeout)
Wait for a notification, with index.
Definition: os_freertos.c:210
OS_STD_RETURN_e OS_NotifyIndexedFromIsr(TaskHandle_t taskToNotify, uint32_t indexToNotify, uint32_t notifiedValue)
Notify a task, with index.
Definition: os_freertos.c:230
void OS_ExitTaskCritical(void)
Exit Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:154
void vApplicationIdleHook(void)
Hook function for the idle task.
Definition: os_freertos.c:124
void OS_EnterTaskCritical(void)
Enter Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:150
OS_STD_RETURN_e OS_SendToBackOfQueue(OS_QUEUE xQueue, const void *const pvItemToQueue, uint32_t ticksToWait)
Post an item to the back the provided queue.
Definition: os_freertos.c:277
void OS_InitializeScheduler(void)
Initialization function for the scheduler.
Definition: os_freertos.c:76
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os_freertos.c:158