Giter VIP home page Giter VIP logo

cmsis-freertos's Introduction

CMSIS-FreeRTOS

This repository contains the CMSIS-RTOS adoption of FreeRTOS-Kernel Version 11.1.0 as it is released as Software Pack on http://www.keil.com/pack. The documentation is available under https://arm-software.github.io/CMSIS-FreeRTOS/.

Use Issues to provide feedback and report problems for CMSIS FreeRTOS implementation.

Use main branch for pull-requests.

Directory Structure

Directory Content
CMSIS CMSIS-FreeRTOS related files
CMSIS/RTOS2/FreeRTOS/Config CMSIS-FreeRTOS configuration file
CMSIS/RTOS2/FreeRTOS/Examples CMSIS-FreeRTOS example projects
CMSIS/RTOS2/FreeRTOS/Source CMSIS-FreeRTOS source code
Documentation Generated documentation placeholder
DoxyGen Source of the documentation
Source FreeRTOS Kernel source code

Generate CMSIS Pack for Release

This GitHub development repository contains all the sources you need to successfully build the pack.

To build the complete pack for installation use the gen_pack.sh bash script. This script file also generates the documentation.

Documentation may be generated separately using the bash script gen_doc.sh (located in ./DoxyGen).

License

The FreeRTOS kernel source files are released under the MIT open source license (read LICENSE.md). The rest of the repository content is covered by Apache 2.0 license (read LICENSE).

cmsis-freertos's People

Contributors

brondani avatar cppbaddy avatar davidskeck avatar jkrech avatar johannestrageser avatar jonatanantoni avatar keilchris avatar lkasperowicz avatar pakluba avatar pvyleta avatar reinhardkeil avatar robertrostohar avatar syvotouf avatar ttornblom avatar vladimirumek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cmsis-freertos's Issues

osTimerNew does not really support static memory allocation

Hi,

The osTimerNew requires pvPortMalloc/pvPortFree, even with only static allocation is selected.

I migrated to CMSIS OS v2 because of explicit support in all the APIs for using static only memory allocation (i.e. owner module allocated memory resources at compile time).

It seems the osTimer API does not so easily allow for this on FreeRTOS as the internal timer construct provides no place to save the function pointer and argument in the Timer Control Block.

My solution was to statically allocate the additional space after the Timer Control Block, and simply pass in a larger cb and size. However, this CMSIS OS v2 FreeRTOS implementation needs to do some magic.

My implementation is a quick and dirty one, but could this idea be useful for you?

So the idea is that the owner statically allocate additional space for the Timer Control Block before calling osTimerNew(...)

*MACRO*
PRIVATE U32 os_timer_cb_##iname[((sizeof(StaticTimer_t) + 3U) / 4U) * 4U + 8U];					
PRIVATE CONST osTimerAttr_t os_timer_attr_##iname =
{															
	#iname,															
	0U,															
	(&os_timer_cb_##iname),
	((sizeof(StaticTimer_t) + 3U) / 4U) * 4U + 8U
}

And then ...

diff --git a/common/rtos/freertos/cmsis-rtos/cmsis_os2.c b/common/rtos/freertos/cmsis-rtos/cmsis_os2.c
index 783191d1..7823ee2e 100755
--- a/common/rtos/freertos/cmsis-rtos/cmsis_os2.c
+++ b/common/rtos/freertos/cmsis-rtos/cmsis_os2.c
@@ -1090,15 +1090,25 @@ static void TimerCallback (TimerHandle_t hTimer) {
 osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) {
   const char *name;
   TimerHandle_t hTimer;
-  TimerCallback_t *callb;
+  TimerCallback_t *callb = NULL;
   UBaseType_t reload;
   int32_t mem;

   hTimer = NULL;

   if ((IRQ_Context() == 0U) && (func != NULL)) {
-    /* Allocate memory to store callback function and argument */
-    callb = pvPortMalloc (sizeof(TimerCallback_t));
+
+    #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
+      /* Allocate memory to store callback function and argument */
+      callb = pvPortMalloc (sizeof(TimerCallback_t));
+    #else
+      if (attr != NULL) {
+        if ((attr->cb_mem != NULL) && (attr->cb_size >= (((sizeof(StaticTimer_t) + (sizeof(void *) - 1)) / sizeof(void *)) * sizeof(void *) + sizeof(TimerCallback_t)))) {
+          uint8_t * callb_ptr = (uint8_t *)attr->cb_mem;
+          callb = (TimerCallback_t *)&callb_ptr[((sizeof(StaticTimer_t) + (sizeof(void *) - 1)) / sizeof(void *)) * sizeof(void *)];
+        }
+      }
+    #endif

     if (callb != NULL) {
       callb->func = func;
@@ -1149,10 +1159,12 @@ osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument,
         }
       }

-      if ((hTimer == NULL) && (callb != NULL)) {
-        /* Failed to create a timer, release allocated resources */
-        vPortFree (callb);
-      }
+      #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
+        if ((hTimer == NULL) && (callb != NULL)) {
+          /* Failed to create a timer, release allocated resources */
+          vPortFree (callb);
+        }
+      #endif
     }
   }

@@ -1256,7 +1268,9 @@ osStatus_t osTimerDelete (osTimerId_t timer_id) {
   TimerHandle_t hTimer = (TimerHandle_t)timer_id;
   osStatus_t stat;
 #ifndef USE_FreeRTOS_HEAP_1
-  TimerCallback_t *callb;
+  #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
+    TimerCallback_t *callb;
+  #endif

   if (IRQ_Context() != 0U) {
     stat = osErrorISR;
@@ -1265,10 +1279,11 @@ osStatus_t osTimerDelete (osTimerId_t timer_id) {
     stat = osErrorParameter;
   }
   else {
-    callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer);
-
     if (xTimerDelete (hTimer, 0) == pdPASS) {
-      vPortFree (callb);
+      #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
+        callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer);
+        vPortFree (callb);
+      #endif
       stat = osOK;
     } else {
       stat = osErrorResource;

vQueueAddToRegistry should not be called if name== NULL

In following code

#if (configQUEUE_REGISTRY_SIZE > 0)
if (hMutex != NULL) {
if (attr != NULL) {
name = attr->name;
} else {
name = NULL;
}
vQueueAddToRegistry (hMutex, name);
}
#endif

vQueueAddToRegistry is called even when name == NULL but it should not as in vQueueAddToRegistry , name == NULL is used to define a free slot, In latest code of freertos an assert has been added
void vQueueAddToRegistry( QueueHandle_t xQueue,
const char * pcQueueName ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
{
UBaseType_t ux;

    configASSERT( xQueue );
    configASSERT( pcQueueName );

We have same issue for other call to vQueueAddToRegistry

cmsis-os2 priorities issue with the FreeRTOS

Hi,
the cmsis-os2.h defines priorities going from:
osPriorityNone = 0, ///< No priority (not initialized).
to
osPriorityISR = 56, ///< Reserved for ISR deferred thread.

FreeRTOS, however, is customising the priorities using the configMAX_PRIORITIES that can't be set
higher than 32, otherwise a compile error occurs, in portmarco.h files.
Added to that, when a thread is created with a priority higher than configMAX_PRIORITIES FreeRTOS is lowering it to: configMAX_PRIORITIES - 1 (check the file tasks.c).

This makes applications misbehave when using multiple threads with different "cmsis-os" priorities that are higher than configMAX_PRIORITIES.

regards
Haithem.

Outdated licensing information - please switch to Apache 2.0

The Readme.md mentions that "CMSIS-FreeRTOS is licensed under the FreeRTOS license." which is however misleading information, as the original FreeRTOS is now under MIT license (since version 10.0.0), and the CMSIS part is under Apache 2.0.

As far as I understand, it would make sense to label this whole project as "licensed under Apache 2.0" as MIT is compatible with it as far as I Understand.

See https://law.stackexchange.com/questions/6081/can-i-bundle-mit-licensed-components-in-a-apache-2-0-licensed-project for discussion on that topic.

10.5.1 regression when the firmware is loaded from a bootloader

I have an application that can be compiled in two different ways:

  • to be executed directly (from the Cortex-M reset)
  • to be started from a bootloader (i.e., vector table relocation, ...)

Everything works fine with CMSIS-FreeRTOS 10.4.6, but when I upgraded the pack to 10.5.1 I see a regression:

  • when the application is executed directly, everything is ok
  • when it's started by a bootloader, this is the call chain
    main() >> HAL_Init(); >> HAL_InitTick(TICK_INT_PRIORITY)
    where
    #define TICK_INT_PRIORITY (15UL) /*!< tick interrupt priority */
    Then
 /* Configure the SysTick IRQ priority */
  if (TickPriority < (1UL << __NVIC_PRIO_BITS))
  {
    HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
    uwTickPrio = TickPriority;
  }

and after that the function void TIM6_DAC_IRQHandler(void) is continously called and nothing else.

I suppose some issue with interrupt priorities.
Does 10.5.1 require a different priority configuration based on 10.4.6?
Is there anything else I can do to debug this regressioin?

HardFault Handler on prvStartFirstTask()

Hi,

I am creating a new test project to use FreeRtos in uvision and STM32F4 with STMCubeMX. When the basic project runs, there is a hardfault handler when it runs the prvStartFirstTask() function on the line svc 0 (Call SVC to start the first task)
I can not find the problem. Any ideas?
I attach the basic project.

Thanks

My cmsis-freertos porting exception randomly

I have ported the CMSIS-freertos to my original cmsis-rtx software, and tested with the default example blinky.c correctly. but it is crashing randomly in my real software.
Here is some information:

### EXCEPTION ###
PC =45DCD2EE, ExceptionNumber=-12
R0 =200A0064, R1 =00000000, R2 =00000000, R3 =2002D3F8
R4 =62E5DFFE, R5 =E7B24843, R6 =05A1FE4F, R7 =1DF6A8E1
R8 =0C406BE6, R9 =766302B2, R10=2000ADBF, R11=FFFED520
R12=2D3D7465, SP =200A9FE0, LR =45DCD2EF
MSP=200A9EAC, PSP=200A0064

PRIMASK=00, FAULTMASK=00, BASEPRI=00, CONTROL=00
XPSR=6100000E, APSR=nZCvq, EPSR=01000000, IPSR=0E

ICSR =04414004, AIRCR=FA050000, SCR  =00000000, CCR  =00000210
SHCSR=00070401, CFSR =00000001, HFSR =00000000, AFSR =00000000
MMFAR=E000ED34, BFAR =E000ED38
FaultInfo : (MemFault)
FaultCause: (Instruction access violation)

200A9FE0: 00000000 00F00000 00000000 2000B474
200A9FF0: 00000018 0C077DB9 0C0779A0 41000000
200AA000: 78407802 2002EA40 BF004770 BA006800
200AA010: BF004770 78007842 2002EA40 BF004770
200AA020: 47706800 70010A0B 47707043 0C0AB410
200AA030: 0A0B0E0C 700170C4 70437082 4B04F85D
200AA040: BF004770 70410A0B 47707003 0C0AB410
200AA050: 0A0B0E0C 70C17004 70837042 4B04F85D

Possible Backtrace:
 C077DB4
total task number 7 current 7


total active task 7

task#1          R       32      1393    6       S/2001e8d0      H/2001e870
app_thread      R       40      314     5       S/20020700      H/200206a4
main            R       24      265     1       S/200a9100      H/2002537c
2               X       12997   0       939708438       S/32c5  H/0
bt_main         R       32      925     7       S/20013998      H/2001393c
IDLE            R       0       491     2       S/20023ec0      H/200246c0
                B       24      381     4       S/200253f0      H/20025bf8
Tmr Svc         B       40      399     3       S/20024720      H/20024f20
task#1          S       32      1393    6       S/2001e8d0      H/2001e870
app_thread      B       40      314     5       S/20020700      H/200206a4
main            S       24      265     1       S/200a9100      H/2002537c
bt_main         S       32      925     7       S/20013998      H/2001393c

The thread information was printed with vTasklist, and the line

2                     X       12997   0       939708438       S/32c5  H/0

is definitely wrong, S/xxxx is add by me with the stack base info
and H/xxxx is the thread handle.
One point is even the device crashes randomly, This line is always same!!

Another problem is there are only 7 tasks, but the vTasklist--> uxTaskGetSystemState
find 12 tasks, some task(such as main) in the different list at same time.
Do you have any advice? thanks a lot.

cmsis_os2 header

Is cmsis_os2.h available?

I'm trying to test CMSIS Freertos but the file is missing. I searched in the release and repository.

CMSIS::RTOS2::FreeRTOS doesn't work if MicroLIB is not used

I found a problem while playing a little bit with FTP Server example from Oryx-Embedded on STM32H743I-EVAL board.
This example works out-of-the-box using RTOS2 interface, implemented through RTX5.
Since the example needs File System from Keil.MDK-Middleware, MicroLIB cannot be used.

If I change RTOS2 implementation from RTX5 to FreeRTOS (downloaded through its own CMSIS pack), the example doesn't work anymore.
The most visible issue is that void HAL_IncTick(void) is never called and the interrupt stays in pending state forever.
Has someone an idea on what could be the reason?

For this reason I investigated deeper inside the sources to find the differences between RTX5 and FreeRTOS implementations behind RTOS2 interface.

I found some strange things inside clib_arm.c (used by CMSIS-FreeRTOS) compared to rtx_lib.c (used by RTX5).
I summarize what I see:

Point 1
This comes from rtx_lib.c
https://github.com/ARM-software/CMSIS_5/blob/b0c7f1933926c805292b0368eb19e55b6646d18b/CMSIS/RTOS2/RTX/Source/rtx_lib.c#L623-L630
where I see osKernelInitialize() is called.
This comes from clib_arm.c

#ifndef __MICROLIB
__WEAK
void _platform_post_stackheap_init (void);
void _platform_post_stackheap_init (void) {
/* Initialize OS, memory, etc. */
#if defined(RTE_Compiler_EventRecorder)
EvrFreeRTOSSetup(0);
#endif
}
#endif /* __MICROLIB */

where I see that nothing is node (apart from Event Recording, which is NOT defined in the FTP Server example).

Point 2
This comes from rtx_lib.c
https://github.com/ARM-software/CMSIS_5/blob/b0c7f1933926c805292b0368eb19e55b6646d18b/CMSIS/RTOS2/RTX/Source/rtx_lib.c#L690-L693
and the define is different from what I see from clib_arm.c

#if (( defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))) && !defined(__MICROLIB))

since RTX_NO_MULTITHREAD_CLIB is missing from this one.

Point 3
This comes from rtx_lib.c
https://github.com/ARM-software/CMSIS_5/blob/b0c7f1933926c805292b0368eb19e55b6646d18b/CMSIS/RTOS2/RTX/Source/rtx_lib.c#L701-L707
where I can see that the variables are placed in a bss.os.libspace region.
This comes from clib_arm.c

/* Libspace memory pool */
static uint32_t os_libspace[OS_THREAD_LIBSPACE_NUM+1][LIBSPACE_SIZE/sizeof(uint32_t)];
/* Array of Threads (IDs) using libspace */
static TaskHandle_t os_libspace_id[OS_THREAD_LIBSPACE_NUM];

where no explicit placement is done.

Point 4
Functions from rtx_lib.c
https://github.com/ARM-software/CMSIS_5/blob/b0c7f1933926c805292b0368eb19e55b6646d18b/CMSIS/RTOS2/RTX/Source/rtx_lib.c#L710-L794
call RTOS2 functions (osKernelGetState(), osThreadGetId(), ...)
On the other side, functions from clib_arm.c

/* OS Kernel state checking */
static uint32_t os_kernel_is_active (void) {
if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
return 1U;
} else {
return 0U;
}
}
/* Provide libspace for current thread */
void *__user_perthread_libspace (void);
void *__user_perthread_libspace (void) {
TaskHandle_t id;
uint32_t n;
if (!os_kernel_is_active()) {
return (void *)&os_libspace[OS_THREAD_LIBSPACE_NUM][0];
}
id = xTaskGetCurrentTaskHandle();
for (n = 0U; n < OS_THREAD_LIBSPACE_NUM; n++) {
if (os_libspace_id[n] == NULL) {
os_libspace_id[n] = id;
return (void *)&os_libspace[n][0];
}
if (os_libspace_id[n] == id) {
return (void *)&os_libspace[n][0];
}
}
return (void *)&os_libspace[n][0];
}
/*----------------------------------------------------------------------------*/
#if (OS_MUTEX_CLIB_NUM > 0)
static StaticSemaphore_t clib_mutex_cb[OS_MUTEX_CLIB_NUM];
static SemaphoreHandle_t clib_mutex_id[OS_MUTEX_CLIB_NUM];
#endif
/* Define mutex object and function prototypes */
typedef void *mutex;
__USED int _mutex_initialize(mutex *m);
__USED void _mutex_acquire (mutex *m);
__USED void _mutex_release (mutex *m);
__USED void _mutex_free (mutex *m);
/* Initialize mutex */
int _mutex_initialize(mutex *m) {
#if (OS_MUTEX_CLIB_NUM > 0)
uint32_t i;
#endif
*m = NULL;
#if (OS_MUTEX_CLIB_NUM > 0)
for (i = 0U; i < OS_MUTEX_CLIB_NUM; i++) {
if (clib_mutex_id[i] == NULL) {
/* Create mutex using static memory */
clib_mutex_id[i] = xSemaphoreCreateMutexStatic(&clib_mutex_cb[i]);
/* Return mutex id */
*m = clib_mutex_id[i];
return 1;
}
}
#endif
if (os_kernel_is_active()) {
/* Create mutex using dynamic memory */
*m = xSemaphoreCreateMutex();
}
if (*m == NULL) {
return 0;
}
return 1;
}
/* Acquire mutex */
void _mutex_acquire(mutex *m) {
if (os_kernel_is_active()) {
xSemaphoreTake(*m, portMAX_DELAY);
}
}
/* Release mutex */
void _mutex_release(mutex *m) {
if (os_kernel_is_active()) {
xSemaphoreGive(*m);
}
}
/* Free mutex */
void _mutex_free(mutex *m) {
#if (OS_MUTEX_CLIB_NUM > 0)
uint32_t i;
#endif
vSemaphoreDelete(*m);
#if (OS_MUTEX_CLIB_NUM > 0)
/* Check if mutex was using static memory */
for (i = 0U; i < OS_MUTEX_CLIB_NUM; i++) {
if (*m == clib_mutex_id[i]) {
clib_mutex_id[i] = NULL;
break;
}
}
#endif
}

call a lot of native FreeRTOS functions (xTaskGetSchedulerState(), xTaskGetCurrentTaskHandle(), ...) and I don't understand if the do exactly what is expected from them.

Does clib_arm.c needs an upgrade to be aligned with rtx_lib.c?

Incorrect timeout handling in osThreadFlagsWait with osFlagsWaitAll

The timeout handling in osThreadFlagsWait when using osFlagsWaitAll is incorrect and can lead to dramatically reduced timeouts.

Imagine a task waiting on two flags A and B with a timeout of 1000ms. The flag A is never set. The flag B is set once every 1ms. osThreadFlagsWait calls xTaskNotifyWait (0, clear, &nval, tout);, where tout is initially 1000ms. xTaskNotifyWait wakes up after 1ms when B is set. tout is then updated as follows:

td = xTaskGetTickCount() - t0;
if (td > tout) {
    tout  = 0;
} else {
    tout -= td;
}

t0 is the starting time of osThreadFlagsWait, so tout becomes 999ms.

xTaskNotifyWait is called again in a loop, so the next time B is set (2ms into the 1000ms timeout), tout becomes 997ms (instead of the correct 998ms). The third time (3ms into the 1000ms timeout), it becomes 997ms - 3ms = 994ms.

In other words, during each iteration, the remaining timeout tout is reduced by the total time waited, not by the time waited in that iteration. In the example above this results in the 1000ms timeout occurring after only 46ms have actually passed.

One possible fix is to change if (td > tout) to if (td > timeout) and tout -= td to tout = timeout - td.

OsThreadNew is incorrectly limiting thread stack size to 64K

In the file cmsis_os2.c :

When the osThreadNew() function calls the FreeRTOS xTaskCreate() function it casts the stack size parameter to an (uint16_t) as seen below:

        #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
          if (xTaskCreate ((TaskFunction_t)func, name, (uint16_t)stack, argument, prio, &hTask) != pdPASS) {
            hTask = NULL;
          }

However, FreeRTOS allows the stack parameter to be defined by the user using configSTACK_DEPTH_TYPE. If the user defines the stack depth to be a uint32_t it could be truncated when cast to a uin16_t. I recommend the cast to be removed or at the very least, cast to configSTACK_DEPTH_TYPE like:

        #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
          if (xTaskCreate((TaskFunction_t)func, name, (configSTACK_DEPTH_TYPE)stack, argument, prio, &hTask) != pdPASS) {
            hTask = NULL;
          }
        #endif

Wrong expression use : mp->sem == NULL in osMemoryPoolNew (cmsis_os2.c)

/* Create a semaphore (max count == initial count == block_count) */
#if (configSUPPORT_STATIC_ALLOCATION == 1)
  mp->sem = xSemaphoreCreateCountingStatic (block_count, block_count, &mp->mem_sem);
#elif (configSUPPORT_DYNAMIC_ALLOCATION == 1)
  mp->sem = xSemaphoreCreateCounting (block_count, block_count);
#else
  mp->sem == NULL; /* Should be "=" instead of "==" */
#endif

osPoolDef compile errors.

#define osPoolDef(name, no, type)
const osPoolDef_t os_pool_def_##name =
{ (no), sizeof(type), NULL }

should be
#define osPoolDef(name, no, type)
const osPoolDef_t os_pool_def_##name =
{ (no), sizeof(type), {NULL} }

because osMemoryPoolAttr_t is a structure.

NVIC_SetPriority() build error.

Hi,
this commit introduced the function SVC_Setup() that is calling the NVIC_SetPriority (SVCall_IRQn, 0U), IIUC, the latter is device dependent i.e. an external header file is defining it.Thus compiling the code within the STM32 Cube FW, the following errors are thrown:
Error[Pe223]: function "NVIC_SetPriority" declared implicitly Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os2.c 173
Error[Pe020]: identifier "SVCall_IRQn" is undefined Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os2.c 173

regards
Haithem.

how can I avoid the crash?

now I run a testcase which cause freertos reboot:

the testcase source code is as below:

1 osStatus_t uwRet;
2 g_cmsisMutexId = osMutexNew(NULL);
3 uwRet = osMutexDelete(g_cmsisMutexId);
4 uwRet = osMutexDelete(g_cmsisMutexId);

when running at 4th line, system will reboot。

Could you please tell me how can I know g_cmsisMutexId is invalid after executiong 3rd line? thanks a lot.

SysTick_Handler conflict M33

Both cmsis_os2.c and the port.c for ARM_CM33 define SysTick_Handlers and they conflict. Older port.c's defined xPortSysTickHandler which could be chosen through config and I think cmsis_os2.c did not define a handler at all - why should it actually ... shouldn't that be left to the OS itself? The handler in cmsis_os2.c can be avoided by getting rid of the SysTick define, but that one is also deeply embedded in the core_*.h files.

What is the correct solution for using cmsis_os2.c on an M33?

osThreadDef macro invalid reference

Trying to use the osThreadDef results in the following error:

main.c:7:13: error: 'blinker' undeclared here (not in a function)
 osThreadDef(blinker, osPriorityNormal, 1, 256);
             ^
../../cmsis_os.h:438:4: note: in definition of macro 'osThreadDef'
 { (name), \
    ^

The first field in the osThreadDef_t structure is a function pointer, which is unused in the FreeRTOS implementation. In addition, the macro sets the thread name to NULL.

Modifying the definition of osThreadDef to the following:

#define osThreadDef(name, priority, instances, stacksz) \
static uint64_t os_thread_stack##name[(stacksz)?(((stacksz+7)/8)):1]; \
static StaticTask_t os_thread_cb_##name; \
const osThreadDef_t os_thread_def_##name = \
{ NULL, \
  { #name, osThreadDetached, \
    (instances == 1) ? (&os_thread_cb_##name) : NULL,\
    (instances == 1) ? sizeof(StaticTask_t) : 0U, \
    ((stacksz) && (instances == 1)) ? (&os_thread_stack##name) : NULL, \
    8*((stacksz+7)/8), \
    (priority), 0U, 0U } }
#endif

Resolves the issue.

osTimer callback parameter value is not argument passed at timer creation

The documentation for the CMISIS osTimerCreate function is described thus:

Create a one-shot or periodic timer and associate it with a callback function argument.

It describes the argument parameter thus:

*argument* | argument to the timer call back function.

However in the CMSIS-FreeRTOS implementation for prvProcessExpiredTimer, the pxCallbackFunction is invoked by passing the timer handle pxTimer itself, instead of the argument (which is also known as the timerID):

pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );

There is no portable way in CMSIS to access the argument given the timer handle. There is a pvTimerGetTimerID() function in FreeRTOS which serves this purpose (though having the caller invoke this would break the encapsulation).

It seems the fix would be for prvProcessExpiredTimer to use pvTimerGetTimerID() to retrieve the timerID/argument and pass this to the callback.

osMessageQueueGet(timeout = osWaitForever) always failed with return code = osErrorParameter since IS_IRQ() predicates True

  1. I'm using CMSIS-FreeRTOS-10.3.1 with a Cortex-M33-NTZ implementation;
  2. simple application: 2 tasks, one message sender, another message receiver, same task priorities;
  3. the message receiver would stuck in its loop without yielding
  4. here is pseudo code of its loop:
void task_receiver(void *parameter)
{
    while (true) {
      if (osOK == osMessageQueueGet(mq_id, &msg, 0, osWaitForever)) {
        // do stuff
      }
    }
}

thanks for your support!

Can CMSIS based thread support osThreadJoinable mode?

I notice that CMSIS based thread only support osThreadDetached mode. I don't know why? Is it the system limitation or another reason?
How can I support both osThreadJoinable and osThreadDetached?

Thanks a lot.

Stream Buffer CMSIS interface?

Hi there,
I would like to implement stream buffers using CMSIS-RTOS.
I there any example where I could get started from?

osThreadGetStackSize() implmentation missing

Hi,
according to the CMSIS-RTOS v2 documentation, there the following API:
uint32_t osThreadGetStackSize ( osThreadId_t thread_id )
this is not implemented in the FreeRTOS port, which may lead to link Errors:

Error[Li005]: no definition for "osThreadGetStackSize"

regards
Haithem.

FreeRTOS config required flags not correctly treated

Hi,
many FreeRTOS config flags are required to be set to 1, but there isn't any check to throw errors when there aren't. some of these the flags are:

  • configUSE_MUTEXES
  • configUSE_RECURSIVE_MUTEXES
  • configUSE_TIMERS
  • configSUPPORT_STATIC_ALLOCATION

is it possible to add checks in the cmsis_os.h to throw "human friendly" errors when a required flag is not correctly set?

regards
Haithem.

about CMSIS-FreeRTOS memory pool management

I am not found memory pool management source code in this project, not implemented?
I am using CMSIS OS version v1.02, the v1.02 cmsis_os.c I can find Memory Pool Management Functions, but there is a TODO:

//TODO
//This is a primitive and inefficient wrapper around the existing FreeRTOS memory management.
//A better implementation will have to modify heap_x.c!

My question is :

  1. is there not implement memory pool on this project, or newest CMSIS-Freertos version.
  2. above TODO, this there have a patch about how to modify heap_x.c to make memory pool better?

Auto clear overflow flag in SysTick_Handler(cmsis_os2) will break `configUSE_TICKLESS_IDLE 1` in freeRTOS

Seems SysTick_Handler in cmsis_os2 will auto clear overflow flag for SysTick_Handler

/*
SysTick handler implementation that also clears overflow flag.
*/
void SysTick_Handler (void) {
/* Clear overflow flag */
SysTick->CTRL;

But it will also break the default implementation of vPortSuppressTicksAndSleep (#define configUSE_TICKLESS_IDLE 1), which required to check the same flag, and it make the wakeup timer almost frozen.

/* Disable the SysTick clock without reading the
* portNVIC_SYSTICK_CTRL_REG register to ensure the
* portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
* the time the SysTick is stopped for is accounted for as best it can
* be, but using the tickless mode will inevitably result in some tiny
* drift of the time maintained by the kernel with respect to calendar
* time*/
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT );
/* Determine if the SysTick clock has already counted to zero and
* been set back to the current reload value (the reload back being
* correct for the entire expected idle time) or if the SysTick is yet
* to count to zero (in which case an interrupt other than the SysTick
* must have brought the system out of sleep mode). */
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )

Is there any way to fix the conflict?

os_tick.h missing

The os_tick.h file is missing. There are multiple references to it in the code, causing compilation failure.

Improve README.md

In README.md I see

The branch master of this GitHub repository contains the CMSIS-RTOS adoption of FreeRTOS Version 10.4.6 as it is released as Software Pack on http://www.keil.com/pack.

I think that the information about FreeRTOS version is a little bit confusing, since the text shows Version 10.4.6 but the link points to Version 202111.00.
And in tbis way it's not clear for the end user if CMSIS-FreeRTOS is up-to-date with upstream FreeRTOS or not.

After my investigation I think that this happens because CMSIS-FreeRTOS is not an adoption of FreeRTOS here, but of FreeRTOS-Kernel here.
And keeping this in mind, everything is much clearer, since FreeRTOS-Kernel is at version 10.4.6.

My suggestion is to change the README.md in this way

The branch master of this GitHub repository contains the CMSIS-RTOS adoption of FreeRTOS-Kernel Version 10.4.6 as it is released as Software Pack on http://www.keil.com/pack.

What do you think?

osDelayUntil() does not work as documented

The main difference between osDelay() and osDelayUntil() is that the former takes a duration and the latter takes an absolute time. As currently implemented for FreeRTOS, osDelayUntil() passes the tick value as the interval parameter to vTaskDelayUntil() which treats it as a duration, not a absolute time.

For instance, I would expect the following thread code to blink an LED at 2Hz (it will with the RTX implementation).

static void ledThread(void *) {
  auto nextWakeTime = osKernelGetTickCount();
  for (;;) {
    nextWakeTime += (250 * osKernelGetTickFreq()) / 1000;
    osDelayUntil(nextWakeTime);
    ledToggle();
  }
}

As currently implemented, the LED will turn on for 250ms, then off for 500ms, then on for 750ms, and so on.

NO cmsis_os2.h

cannot find "cmsis_os2.h" that included in some source files

osThreadNew creates a high-priority task, which is scheduled first and then returns to osThreadId_t

In such a situation, there is already one byte of data in uart rx fifo. The low-priority task sys_up_task calls osThreadNew to create the high-priority task uart_rx_task, used to starts the uart interrupt , turns on uart rx and dispatch rx data. At this time, osThreadNew function does not return uart_rx_task's handle, but the interrupt happened and sends this byte to uart_rx_task. Because the handle is not obtained, this byte of data is lost

osEventFlagsSet fails with called from ISR

if (xEventGroupSetBitsFromISR (hEventGroup, (EventBits_t)flags, &yield)  != pdFAIL) {
  rflags = (uint32_t)osErrorResource;
} else {
  rflags = flags;
  portYIELD_FROM_ISR (yield);
}

osThreadGetStackSpace() returns words instead of bytes

The documentation for osThreadGetStackSpace() states that it returns the remaining stack space in bytes. The implementation uses uxTaskGetStackHighWaterMark() which returns the number of words.

The result should be multiplied by sizeof(StackType_t) to return the number of bytes

osDelayUntil implementation is wrong

According to RTOS2 API ticks parameter specifies absolute time in ticks to wait for. See my comments in the code excerpt:
osStatus_t osDelayUntil (uint32_t ticks) {
TickType_t tcnt;
osStatus_t stat;

if (IS_IRQ()) {
stat = osErrorISR;
}
else {
stat = osOK;
tcnt = xTaskGetTickCount();

//vTaskDelayUntil (&tcnt, (TickType_t)ticks); <- second parameter must be ticks to wait
vTaskDelayUntil (&tcnt, (TickType_t)(ticks - tcnt));  // proposed fix

}

return (stat);
}

No MemPool functions

Why did you not implement some function for cmsis_os2.h?
For instance, mempool, thread, kernel... like followings..

Memory Pool functions are not implemented and will always return with error.

  • \b osMemoryPoolAlloc: \token{not implemented}
  • \b osMemoryPoolDelete: \token{not implemented}
  • \b osMemoryPoolFree: \token{not implemented}
  • \b osMemoryPoolGetBlockSize: \token{not implemented}
  • \b osMemoryPoolGetCapacity: \token{not implemented}
  • \b osMemoryPoolGetCount: \token{not implemented}
  • \b osMemoryPoolGetName: \token{not implemented}
  • \b osMemoryPoolGetSpace: \token{not implemented}
  • \b osMemoryPoolNew: \token{not implemented}

CMSIS-RTOS2: osMutexNew() failed with 'osMutexRobust' atrribute

With CMSIS-RTOS2, when using 'osMutexNew()' with 'osMuteRobus', it will return 'NULL'. Try the code below, and you'll repeat the failure:

  static const osMutexAttr_t at = {NULL, osMutexPrioInherit | osMutexRecursive | osMutexRobust, NULL, NULL};
    osMutexId_t id;

    id = osMutexNew(&at);

    if (id == NULL)
    {
        printf("Failed to create a mutex\n");
    }

The similar code is used in Lwip 2.1.2, 'sys_arch.c', function: 'sys_mutex_new()'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.