foxBMS  1.5.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-02-03 (date of last update)
47  * @version v1.5.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 "ftask.h"
61 
62 #include <stdint.h>
63 
64 /*========== Macros and Definitions =========================================*/
65 
66 /*========== Static Constant and Variable Definitions =======================*/
67 
68 /*========== Extern Constant and Variable Definitions =======================*/
69 
70 /*========== Static Function Prototypes =====================================*/
71 
72 /*========== Static Function Implementations ================================*/
73 
74 /*========== Extern Function Implementations ================================*/
75 extern void OS_InitializeScheduler(void) {
76  if (OS_ENABLE_CACHE == true) {
77  _cacheEnable_();
78  }
79 }
80 
81 void OS_StartScheduler(void) {
82  vTaskStartScheduler();
83  /* This function should never return */
85 }
86 
88  StaticTask_t **ppxIdleTaskTCBBuffer,
89  StackType_t **ppxIdleTaskStackBuffer,
90  uint32_t *pulIdleTaskStackSize) {
91  /** Buffer for the Idle Task's structure */
92  static StaticTask_t os_idleTask = {0};
93  /** @brief Stack for the Idle task */
94  static StackType_t os_stackSizeIdle[OS_IDLE_TASK_STACK_SIZE] = {0};
95  FAS_ASSERT(ppxIdleTaskTCBBuffer != NULL_PTR);
96  FAS_ASSERT(ppxIdleTaskStackBuffer != NULL_PTR);
97  FAS_ASSERT(pulIdleTaskStackSize != NULL_PTR);
98  *ppxIdleTaskTCBBuffer = &os_idleTask;
99  *ppxIdleTaskStackBuffer = &os_stackSizeIdle[0];
100  *pulIdleTaskStackSize = OS_IDLE_TASK_STACK_SIZE;
101 }
102 
103 #if (configUSE_TIMERS > 0) && (configSUPPORT_STATIC_ALLOCATION == 1)
104 void vApplicationGetTimerTaskMemory(
105  StaticTask_t **ppxTimerTaskTCBBuffer,
106  StackType_t **ppxTimerTaskStackBuffer,
107  uint32_t *pulTimerTaskStackSize) {
108 #if (configUSE_TIMERS > 0) && (configSUPPORT_STATIC_ALLOCATION == 1)
109  /** Buffer for the Timer Task's structure */
110  static StaticTask_t os_timerTask;
111 #endif /* configUSE_TIMERS */
112 
113 #if (configUSE_TIMERS > 0) && (configSUPPORT_STATIC_ALLOCATION == 1)
114  /** Stack for the Timer Task */
115  static StackType_t os_stackSizeTimer[OS_TIMER_TASK_STACK_SIZE];
116 #endif /* configUSE_TIMERS */
117  *ppxTimerTaskTCBBuffer = &os_timerTask;
118  *ppxTimerTaskStackBuffer = &os_stackSizeTimer[0];
119  *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
120 }
121 #endif /* configUSE_TIMERS */
122 
125 }
126 
127 #if (configCHECK_FOR_STACK_OVERFLOW > 0)
128 /* FreeRTOS internal function, keep FreeRTOS types */
129 void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) {
131 }
132 #endif /* configCHECK_FOR_STACK_OVERFLOW */
133 
135  taskENTER_CRITICAL();
136 }
137 
139  taskEXIT_CRITICAL();
140 }
141 
142 uint32_t OS_GetTickCount(void) {
143  return xTaskGetTickCount(); /*TMS570 does not support nested interrupts*/
144 }
145 
146 void OS_DelayTaskUntil(uint32_t *pPreviousWakeTime, uint32_t milliseconds) {
147  FAS_ASSERT(pPreviousWakeTime != NULL_PTR);
148  FAS_ASSERT(milliseconds > 0u);
149  uint32_t ticks = (milliseconds / OS_TICK_RATE_MS);
150  if ((uint32_t)ticks < 1u) {
151  ticks = 1u; /* Minimum delay is 1 tick */
152  }
153  vTaskDelayUntil((TickType_t *)pPreviousWakeTime, (TickType_t)ticks);
154 }
155 
157  vPortTaskUsesFPU();
158 }
159 
160 extern OS_STD_RETURN_e OS_WaitForNotification(uint32_t *pNotifiedValue, uint32_t timeout) {
161  /* AXIVION Routine Generic-MissingParameterAssert: timeout: parameter accepts whole range */
162  FAS_ASSERT(pNotifiedValue != NULL_PTR);
163 
164  OS_STD_RETURN_e notificationReceived = OS_FAIL;
165  /* FreeRTOS: This function must not be used in an interrupt service routine. */
166  /* ulBitsToClearOnEntry and ulBitsToClearOnExit set to 0xffffffff
167  to clear all the bits in the task's notification value */
168  BaseType_t xNotificationReceived = xTaskNotifyWait(UINT32_MAX, UINT32_MAX, pNotifiedValue, timeout);
169  /* FreeRTOS:xTaskNotifyWait returns pdTRUE if notification was received (otherwise pdFALSE). */
170  if (xNotificationReceived == pdTRUE) {
171  notificationReceived = OS_SUCCESS;
172  }
173  return notificationReceived;
174 }
175 
176 extern OS_STD_RETURN_e OS_NotifyFromIsr(TaskHandle_t taskToNotify, uint32_t notifiedValue) {
177  /* AXIVION Routine Generic-MissingParameterAssert: notifiedValue: parameter accepts whole range */
178  FAS_ASSERT(taskToNotify != NULL_PTR);
179 
180  OS_STD_RETURN_e notification = OS_FAIL;
181  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
182  /* Return value dependent on the value of the eAction parameter, here set to eSetValueWithOverwrite */
183  BaseType_t xNotification =
184  xTaskNotifyFromISR(taskToNotify, notifiedValue, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
185  if (xNotification == pdTRUE) {
186  notification = OS_SUCCESS;
187  }
188  /* Make the scheduler yield when notification made, so that unblocked tasks is run immediately
189  (if priorities allow it, instead of waiting for the next OS tick) */
190  portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
191  return notification;
192 }
193 
195  uint32_t indexToWaitOn,
196  uint32_t *pNotifiedValue,
197  uint32_t timeout) {
198  /* AXIVION Routine Generic-MissingParameterAssert: timeout: parameter accepts whole range */
199  FAS_ASSERT(pNotifiedValue != NULL_PTR);
200 
201  OS_STD_RETURN_e notificationReceived = OS_FAIL;
202  /* FreeRTOS: This function must not be used in an interrupt service routine. */
203  /* ulBitsToClearOnEntry and ulBitsToClearOnExit set to 0xffffffff
204  to clear all the bits in the task's notification value */
205  BaseType_t xNotificationReceived =
206  xTaskNotifyWaitIndexed(indexToWaitOn, UINT32_MAX, UINT32_MAX, pNotifiedValue, timeout);
207  /* FreeRTOS:xTaskNotifyWait returns pdTRUE if notification was received (otherwise pdFALSE). */
208  if (xNotificationReceived == pdTRUE) {
209  notificationReceived = OS_SUCCESS;
210  }
211  return notificationReceived;
212 }
213 
215  TaskHandle_t taskToNotify,
216  uint32_t indexToNotify,
217  uint32_t notifiedValue) {
218  /* AXIVION Routine Generic-MissingParameterAssert: notifiedValue: parameter accepts whole range */
219  FAS_ASSERT(taskToNotify != NULL_PTR);
220 
221  OS_STD_RETURN_e notification = OS_FAIL;
222  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
223  /* Return value dependent on the value of the eAction parameter, here set to eSetValueWithOverwrite */
224  BaseType_t xNotification = xTaskNotifyIndexedFromISR(
225  taskToNotify, indexToNotify, notifiedValue, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
226  if (xNotification == pdTRUE) {
227  notification = OS_SUCCESS;
228  }
229  /* Make the scheduler yield when notification made, so that unblocked tasks is run imediately
230  (if priorities allow it, instead of waiting for the next OS tick) */
231  portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
232  return notification;
233 }
234 
235 extern OS_STD_RETURN_e OS_ClearNotificationIndexed(uint32_t indexToClear) {
236  /* AXIVION Routine Generic-MissingParameterAssert: indexToClear: parameter accepts whole range */
237 
238  OS_STD_RETURN_e notificationWasPending = OS_FAIL;
239  /* NULL passed for task handle: the clear is made for the calling task */
240  BaseType_t xNotificationWasPending = xTaskNotifyStateClearIndexed(NULL, indexToClear);
241  /* FreeRTOS:xTaskNotifyStateClearIndexed returns pdTRUE if a notification was pending (otherwise pdFALSE). */
242  if (xNotificationWasPending == pdTRUE) {
243  notificationWasPending = OS_SUCCESS;
244  }
245  return notificationWasPending;
246 }
247 
248 extern OS_STD_RETURN_e OS_ReceiveFromQueue(OS_QUEUE xQueue, void *const pvBuffer, uint32_t ticksToWait) {
249  FAS_ASSERT(pvBuffer != NULL_PTR);
250 
251  OS_STD_RETURN_e queueReceiveSuccessfully = OS_FAIL;
252  /* FreeRTOS: This function must not be used in an interrupt service routine. */
253  BaseType_t xQueueReceiveSuccess = xQueueReceive(xQueue, pvBuffer, (TickType_t)ticksToWait);
254  /* FreeRTOS:xQueueReceive returns pdTRUE if an item was successfully received from the queue (otherwise pdFALSE). */
255  if (xQueueReceiveSuccess == pdTRUE) {
256  queueReceiveSuccessfully = OS_SUCCESS;
257  }
258  return queueReceiveSuccessfully;
259 }
260 
261 extern OS_STD_RETURN_e OS_SendToBackOfQueue(OS_QUEUE xQueue, const void *const pvItemToQueue, uint32_t ticksToWait) {
262  FAS_ASSERT(pvItemToQueue != NULL_PTR);
263 
264  OS_STD_RETURN_e queueSendSuccessfully = OS_FAIL;
265  BaseType_t xQueueSendSuccess = xQueueSendToBack(xQueue, pvItemToQueue, (TickType_t)ticksToWait);
266  /* FreeRTOS:xQueueSendToBack returns pdTRUE if the item was successfully posted (otherwise errQUEUE_FULL). */
267  if (xQueueSendSuccess == pdTRUE) {
268  queueSendSuccessfully = OS_SUCCESS;
269  }
270  return queueSendSuccessfully;
271 }
272 
274  OS_QUEUE xQueue,
275  const void *const pvItemToQueue,
276  long *const pxHigherPriorityTaskWoken) {
277  FAS_ASSERT(pvItemToQueue != NULL_PTR);
278 
279  OS_STD_RETURN_e queueSendSuccessfully = OS_FAIL;
280  BaseType_t xQueueSendSuccess =
281  xQueueSendToBackFromISR(xQueue, pvItemToQueue, (BaseType_t *)pxHigherPriorityTaskWoken);
282  /* FreeRTOS:xQueueSendToBackFromISR 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 
289 extern uint32_t OS_GetNumberOfStoredMessagesInQueue(OS_QUEUE xQueue) {
290  long numberOfMessages = uxQueueMessagesWaiting(xQueue);
291  return (uint32_t)numberOfMessages;
292 }
293 
294 /*========== Externalized Static Function Implementations (Unit Test) =======*/
295 #ifdef UNITY_UNIT_TEST
296 #endif
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:254
#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:310
Declaration of the OS wrapper interface.
OS_STD_RETURN_e
Definition: os.h:82
@ OS_SUCCESS
Definition: os.h:83
@ OS_FAIL
Definition: os.h:84
OS_STD_RETURN_e OS_NotifyFromIsr(TaskHandle_t taskToNotify, uint32_t notifiedValue)
Notify a task.
Definition: os_freertos.c:176
OS_STD_RETURN_e OS_WaitForNotification(uint32_t *pNotifiedValue, uint32_t timeout)
Wait for a notification.
Definition: os_freertos.c:160
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize)
Definition: os_freertos.c:87
OS_STD_RETURN_e OS_ClearNotificationIndexed(uint32_t indexToClear)
Clear pending notification of a task, with index.
Definition: os_freertos.c:235
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:248
void OS_StartScheduler(void)
Starts the operating system scheduler.
Definition: os_freertos.c:81
void OS_DelayTaskUntil(uint32_t *pPreviousWakeTime, uint32_t milliseconds)
Delay a task until a specified time.
Definition: os_freertos.c:146
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:273
void OS_MarkTaskAsRequiringFpuContext(void)
Marks the current task as requiring FPU context.
Definition: os_freertos.c:156
uint32_t OS_GetNumberOfStoredMessagesInQueue(OS_QUEUE xQueue)
Check if messages are waiting for queue.
Definition: os_freertos.c:289
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:194
OS_STD_RETURN_e OS_NotifyIndexedFromIsr(TaskHandle_t taskToNotify, uint32_t indexToNotify, uint32_t notifiedValue)
Notify a task, with index.
Definition: os_freertos.c:214
void OS_ExitTaskCritical(void)
Exit Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:138
void vApplicationIdleHook(void)
Hook function for the idle task.
Definition: os_freertos.c:123
void OS_EnterTaskCritical(void)
Enter Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:134
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:261
void OS_InitializeScheduler(void)
Initialization function for the scheduler.
Definition: os_freertos.c:75
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os_freertos.c:142