mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -04:00
Merge branch 'main' into stack_overflow_check
This commit is contained in:
commit
3d82c5d617
19
MISRA.md
19
MISRA.md
|
@ -115,6 +115,25 @@ _Ref 11.5.5_
|
||||||
because data storage buffers are implemented as uint8_t arrays for the
|
because data storage buffers are implemented as uint8_t arrays for the
|
||||||
ease of sizing, alignment and access.
|
ease of sizing, alignment and access.
|
||||||
|
|
||||||
|
#### Rule 14.3
|
||||||
|
|
||||||
|
MISRA C-2012 Rule 14.3: Controlling expressions shall not be invariant.
|
||||||
|
|
||||||
|
_Ref 14.3_
|
||||||
|
- The `configMAX_TASK_NAME_LEN` and `taskRESERVED_TASK_NAME_LENGTH` are
|
||||||
|
evaluated to constants at compile time and may vary based on the build
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
#### Rule 18.1
|
||||||
|
|
||||||
|
MISRA C-2012 Rule 18.1: A pointer resulting from arithmetic on a pointer operand
|
||||||
|
shall address an element of the same array as that pointer operand.
|
||||||
|
|
||||||
|
_Ref 18.1_
|
||||||
|
- Array access remains within bounds since either the null terminator in
|
||||||
|
the IDLE task name will break the loop, or the loop will break normally
|
||||||
|
if the array size is smaller than the IDLE task name length.
|
||||||
|
|
||||||
#### Rule 21.6
|
#### Rule 21.6
|
||||||
|
|
||||||
MISRA C-2012 Rule 21.6: The Standard Library input/output functions shall not
|
MISRA C-2012 Rule 21.6: The Standard Library input/output functions shall not
|
||||||
|
|
67
portable/ThirdParty/GCC/Posix/port.c
vendored
67
portable/ThirdParty/GCC/Posix/port.c
vendored
|
@ -119,14 +119,20 @@ static void prvResumeThread( Thread_t * xThreadId );
|
||||||
static void vPortSystemTickHandler( int sig );
|
static void vPortSystemTickHandler( int sig );
|
||||||
static void vPortStartFirstTask( void );
|
static void vPortStartFirstTask( void );
|
||||||
static void prvPortYieldFromISR( void );
|
static void prvPortYieldFromISR( void );
|
||||||
|
static void prvThreadKeyDestructor( void * pvData );
|
||||||
|
static void prvInitThreadKey( void );
|
||||||
|
static void prvMarkAsFreeRTOSThread( void );
|
||||||
|
static BaseType_t prvIsFreeRTOSThread( void );
|
||||||
|
static void prvDestroyThreadKey( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void prvThreadKeyDestructor( void * data )
|
static void prvThreadKeyDestructor( void * pvData )
|
||||||
{
|
{
|
||||||
free( data );
|
free( pvData );
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvInitThreadKey()
|
static void prvInitThreadKey( void )
|
||||||
{
|
{
|
||||||
pthread_mutex_lock( &xThreadMutex );
|
pthread_mutex_lock( &xThreadMutex );
|
||||||
|
|
||||||
|
@ -137,24 +143,39 @@ static void prvInitThreadKey()
|
||||||
|
|
||||||
pthread_mutex_unlock( &xThreadMutex );
|
pthread_mutex_unlock( &xThreadMutex );
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvMarkAsFreeRTOSThread( pthread_t thread )
|
static void prvMarkAsFreeRTOSThread( void )
|
||||||
{
|
{
|
||||||
|
uint8_t * pucThreadData = NULL;
|
||||||
|
|
||||||
prvInitThreadKey();
|
prvInitThreadKey();
|
||||||
uint8_t * thread_data = malloc( 1 );
|
|
||||||
configASSERT( thread_data != NULL );
|
|
||||||
*thread_data = 1;
|
|
||||||
pthread_setspecific( xThreadKey, thread_data );
|
|
||||||
}
|
|
||||||
|
|
||||||
static BaseType_t prvIsFreeRTOSThread( pthread_t thread )
|
pucThreadData = malloc( 1 );
|
||||||
|
configASSERT( pucThreadData != NULL );
|
||||||
|
|
||||||
|
*pucThreadData = 1;
|
||||||
|
|
||||||
|
pthread_setspecific( xThreadKey, pucThreadData );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static BaseType_t prvIsFreeRTOSThread( void )
|
||||||
{
|
{
|
||||||
uint8_t * thread_data = ( uint8_t * ) pthread_getspecific( xThreadKey );
|
uint8_t * pucThreadData = NULL;
|
||||||
|
BaseType_t xRet = pdFALSE;
|
||||||
|
|
||||||
return thread_data != NULL && *thread_data == 1;
|
pucThreadData = ( uint8_t * ) pthread_getspecific( xThreadKey );
|
||||||
|
if( ( pucThreadData != NULL ) && ( *pucThreadData == 1 ) )
|
||||||
|
{
|
||||||
|
xRet = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xRet;
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvDestroyThreadKey()
|
static void prvDestroyThreadKey( void )
|
||||||
{
|
{
|
||||||
pthread_key_delete( xThreadKey );
|
pthread_key_delete( xThreadKey );
|
||||||
}
|
}
|
||||||
|
@ -309,7 +330,7 @@ void vPortEndScheduler( void )
|
||||||
( void ) pthread_kill( hMainThread, SIG_RESUME );
|
( void ) pthread_kill( hMainThread, SIG_RESUME );
|
||||||
|
|
||||||
/* Waiting to be deleted here. */
|
/* Waiting to be deleted here. */
|
||||||
if( prvIsFreeRTOSThread( pthread_self() ) == pdTRUE )
|
if( prvIsFreeRTOSThread() == pdTRUE )
|
||||||
{
|
{
|
||||||
pxCurrentThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
|
pxCurrentThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
|
||||||
event_wait( pxCurrentThread->ev );
|
event_wait( pxCurrentThread->ev );
|
||||||
|
@ -369,7 +390,7 @@ void vPortYield( void )
|
||||||
|
|
||||||
void vPortDisableInterrupts( void )
|
void vPortDisableInterrupts( void )
|
||||||
{
|
{
|
||||||
if( prvIsFreeRTOSThread( pthread_self() ) == pdTRUE )
|
if( prvIsFreeRTOSThread() == pdTRUE )
|
||||||
{
|
{
|
||||||
pthread_sigmask(SIG_BLOCK, &xAllSignals, NULL);
|
pthread_sigmask(SIG_BLOCK, &xAllSignals, NULL);
|
||||||
}
|
}
|
||||||
|
@ -378,9 +399,9 @@ void vPortDisableInterrupts( void )
|
||||||
|
|
||||||
void vPortEnableInterrupts( void )
|
void vPortEnableInterrupts( void )
|
||||||
{
|
{
|
||||||
if( prvIsFreeRTOSThread( pthread_self() ) == pdTRUE )
|
if( prvIsFreeRTOSThread() == pdTRUE )
|
||||||
{
|
{
|
||||||
pthread_sigmask(SIG_UNBLOCK, &xAllSignals, NULL);
|
pthread_sigmask( SIG_UNBLOCK, &xAllSignals, NULL );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -417,9 +438,9 @@ static void * prvTimerTickHandler( void * arg )
|
||||||
{
|
{
|
||||||
( void ) arg;
|
( void ) arg;
|
||||||
|
|
||||||
prvMarkAsFreeRTOSThread( pthread_self() );
|
prvMarkAsFreeRTOSThread();
|
||||||
|
|
||||||
prvPortSetCurrentThreadName("Scheduler timer");
|
prvPortSetCurrentThreadName( "Scheduler timer" );
|
||||||
|
|
||||||
while( xTimerTickThreadShouldRun )
|
while( xTimerTickThreadShouldRun )
|
||||||
{
|
{
|
||||||
|
@ -451,7 +472,7 @@ void prvSetupTimerInterrupt( void )
|
||||||
|
|
||||||
static void vPortSystemTickHandler( int sig )
|
static void vPortSystemTickHandler( int sig )
|
||||||
{
|
{
|
||||||
if( prvIsFreeRTOSThread( pthread_self() ) == pdTRUE )
|
if( prvIsFreeRTOSThread() == pdTRUE )
|
||||||
{
|
{
|
||||||
Thread_t * pxThreadToSuspend;
|
Thread_t * pxThreadToSuspend;
|
||||||
Thread_t * pxThreadToResume;
|
Thread_t * pxThreadToResume;
|
||||||
|
@ -473,7 +494,9 @@ static void vPortSystemTickHandler( int sig )
|
||||||
}
|
}
|
||||||
|
|
||||||
uxCriticalNesting--;
|
uxCriticalNesting--;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
fprintf( stderr, "vPortSystemTickHandler called from non-FreeRTOS thread\n" );
|
fprintf( stderr, "vPortSystemTickHandler called from non-FreeRTOS thread\n" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -508,7 +531,7 @@ static void * prvWaitForStart( void * pvParams )
|
||||||
{
|
{
|
||||||
Thread_t * pxThread = pvParams;
|
Thread_t * pxThread = pvParams;
|
||||||
|
|
||||||
prvMarkAsFreeRTOSThread( pthread_self() );
|
prvMarkAsFreeRTOSThread();
|
||||||
|
|
||||||
prvSuspendSelf( pxThread );
|
prvSuspendSelf( pxThread );
|
||||||
|
|
||||||
|
|
|
@ -35,9 +35,11 @@
|
||||||
struct event
|
struct event
|
||||||
{
|
{
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
|
pthread_mutexattr_t mutexattr;
|
||||||
pthread_cond_t cond;
|
pthread_cond_t cond;
|
||||||
bool event_triggered;
|
bool event_triggered;
|
||||||
};
|
};
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
struct event * event_create( void )
|
struct event * event_create( void )
|
||||||
{
|
{
|
||||||
|
@ -46,23 +48,36 @@ struct event * event_create( void )
|
||||||
if( ev != NULL )
|
if( ev != NULL )
|
||||||
{
|
{
|
||||||
ev->event_triggered = false;
|
ev->event_triggered = false;
|
||||||
pthread_mutex_init( &ev->mutex, NULL );
|
pthread_mutexattr_init( &ev->mutexattr );
|
||||||
|
#ifndef __APPLE__
|
||||||
|
pthread_mutexattr_setrobust( &ev->mutexattr, PTHREAD_MUTEX_ROBUST );
|
||||||
|
#endif
|
||||||
|
pthread_mutex_init( &ev->mutex, &ev->mutexattr );
|
||||||
pthread_cond_init( &ev->cond, NULL );
|
pthread_cond_init( &ev->cond, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
return ev;
|
return ev;
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void event_delete( struct event * ev )
|
void event_delete( struct event * ev )
|
||||||
{
|
{
|
||||||
pthread_mutex_destroy( &ev->mutex );
|
pthread_mutex_destroy( &ev->mutex );
|
||||||
|
pthread_mutexattr_destroy( &ev->mutexattr );
|
||||||
pthread_cond_destroy( &ev->cond );
|
pthread_cond_destroy( &ev->cond );
|
||||||
free( ev );
|
free( ev );
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
bool event_wait( struct event * ev )
|
bool event_wait( struct event * ev )
|
||||||
{
|
{
|
||||||
pthread_mutex_lock( &ev->mutex );
|
if( pthread_mutex_lock( &ev->mutex ) == EOWNERDEAD )
|
||||||
|
{
|
||||||
|
#ifndef __APPLE__
|
||||||
|
/* If the thread owning the mutex died, make the mutex consistent. */
|
||||||
|
pthread_mutex_consistent( &ev->mutex );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
while( ev->event_triggered == false )
|
while( ev->event_triggered == false )
|
||||||
{
|
{
|
||||||
|
@ -73,6 +88,8 @@ bool event_wait( struct event * ev )
|
||||||
pthread_mutex_unlock( &ev->mutex );
|
pthread_mutex_unlock( &ev->mutex );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
bool event_wait_timed( struct event * ev,
|
bool event_wait_timed( struct event * ev,
|
||||||
time_t ms )
|
time_t ms )
|
||||||
{
|
{
|
||||||
|
@ -82,7 +99,13 @@ bool event_wait_timed( struct event * ev,
|
||||||
clock_gettime( CLOCK_REALTIME, &ts );
|
clock_gettime( CLOCK_REALTIME, &ts );
|
||||||
ts.tv_sec += ms / 1000;
|
ts.tv_sec += ms / 1000;
|
||||||
ts.tv_nsec += ( ( ms % 1000 ) * 1000000 );
|
ts.tv_nsec += ( ( ms % 1000 ) * 1000000 );
|
||||||
pthread_mutex_lock( &ev->mutex );
|
if( pthread_mutex_lock( &ev->mutex ) == EOWNERDEAD )
|
||||||
|
{
|
||||||
|
#ifndef __APPLE__
|
||||||
|
/* If the thread owning the mutex died, make the mutex consistent. */
|
||||||
|
pthread_mutex_consistent( &ev->mutex );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
while( ( ev->event_triggered == false ) && ( ret == 0 ) )
|
while( ( ev->event_triggered == false ) && ( ret == 0 ) )
|
||||||
{
|
{
|
||||||
|
@ -98,11 +121,19 @@ bool event_wait_timed( struct event * ev,
|
||||||
pthread_mutex_unlock( &ev->mutex );
|
pthread_mutex_unlock( &ev->mutex );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void event_signal( struct event * ev )
|
void event_signal( struct event * ev )
|
||||||
{
|
{
|
||||||
pthread_mutex_lock( &ev->mutex );
|
if( pthread_mutex_lock( &ev->mutex ) == EOWNERDEAD )
|
||||||
|
{
|
||||||
|
#ifndef __APPLE__
|
||||||
|
/* If the thread owning the mutex died, make the mutex consistent. */
|
||||||
|
pthread_mutex_consistent( &ev->mutex );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
ev->event_triggered = true;
|
ev->event_triggered = true;
|
||||||
pthread_cond_signal( &ev->cond );
|
pthread_cond_signal( &ev->cond );
|
||||||
pthread_mutex_unlock( &ev->mutex );
|
pthread_mutex_unlock( &ev->mutex );
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
46
tasks.c
46
tasks.c
|
@ -156,6 +156,23 @@
|
||||||
#define configIDLE_TASK_NAME "IDLE"
|
#define configIDLE_TASK_NAME "IDLE"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ( configNUMBER_OF_CORES > 1 )
|
||||||
|
/* Reserve space for Core ID and null termination. */
|
||||||
|
#if ( configMAX_TASK_NAME_LEN < 2U )
|
||||||
|
#error Minimum required task name length is 2. Please increase configMAX_TASK_NAME_LEN.
|
||||||
|
#endif
|
||||||
|
#define taskRESERVED_TASK_NAME_LENGTH 2U
|
||||||
|
|
||||||
|
#elif ( configNUMBER_OF_CORES > 9 )
|
||||||
|
#warning Please increase taskRESERVED_TASK_NAME_LENGTH. 1 character is insufficient to store the core ID.
|
||||||
|
#else
|
||||||
|
/* Reserve space for null termination. */
|
||||||
|
#if ( configMAX_TASK_NAME_LEN < 1U )
|
||||||
|
#error Minimum required task name length is 1. Please increase configMAX_TASK_NAME_LEN.
|
||||||
|
#endif
|
||||||
|
#define taskRESERVED_TASK_NAME_LENGTH 1U
|
||||||
|
#endif /* if ( ( configNUMBER_OF_CORES > 1 ) */
|
||||||
|
|
||||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 )
|
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 )
|
||||||
|
|
||||||
/* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is
|
/* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is
|
||||||
|
@ -3527,21 +3544,26 @@ static BaseType_t prvCreateIdleTasks( void )
|
||||||
BaseType_t xCoreID;
|
BaseType_t xCoreID;
|
||||||
char cIdleName[ configMAX_TASK_NAME_LEN ] = { 0 };
|
char cIdleName[ configMAX_TASK_NAME_LEN ] = { 0 };
|
||||||
TaskFunction_t pxIdleTaskFunction = NULL;
|
TaskFunction_t pxIdleTaskFunction = NULL;
|
||||||
BaseType_t xIdleTaskNameIndex;
|
UBaseType_t xIdleTaskNameIndex;
|
||||||
BaseType_t xIdleNameLen;
|
|
||||||
BaseType_t xCopyLen;
|
|
||||||
|
|
||||||
configASSERT( ( configIDLE_TASK_NAME != NULL ) && ( configMAX_TASK_NAME_LEN > 3 ) );
|
/* MISRA Ref 14.3.1 [Configuration dependent invariant] */
|
||||||
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-143. */
|
||||||
/* The length of the idle task name is limited to the minimum of the length
|
/* coverity[misra_c_2012_rule_14_3_violation] */
|
||||||
* of configIDLE_TASK_NAME and configMAX_TASK_NAME_LEN - 2, keeping space
|
for( xIdleTaskNameIndex = 0U; xIdleTaskNameIndex < ( configMAX_TASK_NAME_LEN - taskRESERVED_TASK_NAME_LENGTH ); xIdleTaskNameIndex++ )
|
||||||
* for the core ID suffix and the null-terminator. */
|
|
||||||
xIdleNameLen = strlen( configIDLE_TASK_NAME );
|
|
||||||
xCopyLen = xIdleNameLen < ( configMAX_TASK_NAME_LEN - 2 ) ? xIdleNameLen : ( configMAX_TASK_NAME_LEN - 2 );
|
|
||||||
|
|
||||||
for( xIdleTaskNameIndex = ( BaseType_t ) 0; xIdleTaskNameIndex < xCopyLen; xIdleTaskNameIndex++ )
|
|
||||||
{
|
{
|
||||||
|
/* MISRA Ref 18.1.1 [Configuration dependent bounds checking] */
|
||||||
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-181. */
|
||||||
|
/* coverity[misra_c_2012_rule_18_1_violation] */
|
||||||
cIdleName[ xIdleTaskNameIndex ] = configIDLE_TASK_NAME[ xIdleTaskNameIndex ];
|
cIdleName[ xIdleTaskNameIndex ] = configIDLE_TASK_NAME[ xIdleTaskNameIndex ];
|
||||||
|
|
||||||
|
if( cIdleName[ xIdleTaskNameIndex ] == ( char ) 0x00 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure null termination. */
|
/* Ensure null termination. */
|
||||||
|
|
Loading…
Reference in a new issue