mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-26 08:21:57 -04:00
239 lines
6 KiB
C
239 lines
6 KiB
C
/*
|
|
* FreeRTOS Kernel V10.4.3
|
|
* Copyright (C) 2020 Synopsys, Inc. or its affiliates. All Rights Reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
* this software and associated documentation files (the "Software"), to deal in
|
|
* the Software without restriction, including without limitation the rights to
|
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
* subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* https://www.FreeRTOS.org
|
|
* https://github.com/FreeRTOS
|
|
*
|
|
*/
|
|
|
|
#if defined( __MW__ )
|
|
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "FreeRTOS.h"
|
|
|
|
#include "queue.h"
|
|
#include "semphr.h"
|
|
#include "task.h"
|
|
|
|
#include "arc/arc_exception.h"
|
|
#include "embARC_toolchain.h"
|
|
#include "embARC_debug.h"
|
|
|
|
#ifdef ENABLE_FREERTOS_TLS_DEBUG
|
|
#define TLS_DEBUG( fmt, ... ) EMBARC_PRINTF( fmt, ## __VA_ARGS__ )
|
|
#else
|
|
#define TLS_DEBUG( fmt, ... )
|
|
#endif
|
|
|
|
/*
|
|
* Runtime routines to execute constructors and
|
|
* destructors for task local storage.
|
|
*/
|
|
extern void __mw_run_tls_dtor();
|
|
extern void __mw_run_tls_ctor();
|
|
|
|
extern uint32_t exc_nest_count;
|
|
|
|
/*
|
|
* Linker generated symbols to mark .tls section addresses
|
|
* first byte .. last byte
|
|
*/
|
|
extern char _ftls[], _etls[];
|
|
#pragma weak _ftls
|
|
#pragma weak _etls
|
|
|
|
void executable_requires_tls_section( void )
|
|
{
|
|
#if _ARC
|
|
for( ; ; )
|
|
{
|
|
_flag( 1 );
|
|
_nop();
|
|
_nop();
|
|
_nop();
|
|
_nop();
|
|
_nop();
|
|
}
|
|
#endif
|
|
}
|
|
#pragma off_inline(executable_requires_tls_section);
|
|
#pragma alias(executable_requires_tls_section, "executable_requires_.tls_section");
|
|
|
|
static void * init_task_tls( void )
|
|
{
|
|
uint32_t len = ( uint32_t ) ( _etls - _ftls );
|
|
void * tls = NULL;
|
|
|
|
#if FREERTOS_HEAP_SEL == 3
|
|
#warning "FreeRTOS TLS support is not compatible with heap 3 solution(FREERTOS_HEAP_SEL=3)!"
|
|
#warning "You can change FREERTOS_HEAP_SEL in freertos.mk to select other heap solution."
|
|
#else
|
|
tls = pvPortMalloc( len );
|
|
#endif
|
|
|
|
if( tls )
|
|
{
|
|
TLS_DEBUG( "Malloc task tls:%dbytes\r\n", len );
|
|
memcpy( tls, _ftls, len );
|
|
__mw_run_tls_ctor(); /* Run constructors */
|
|
}
|
|
|
|
return tls;
|
|
}
|
|
|
|
static void free_task_tls( void * pxTCB )
|
|
{
|
|
TaskHandle_t task2free = ( TaskHandle_t ) pxTCB;
|
|
|
|
if( task2free != NULL )
|
|
{
|
|
void * tls = pvTaskGetThreadLocalStoragePointer( task2free, 0 );
|
|
|
|
if( tls )
|
|
{
|
|
TLS_DEBUG( "Free task tls\r\n" );
|
|
__mw_run_tls_dtor();
|
|
vPortFree( tls );
|
|
vTaskSetThreadLocalStoragePointer( task2free, 0, NULL );
|
|
}
|
|
}
|
|
}
|
|
|
|
void task_end_hook( void * pxTCB )
|
|
{
|
|
free_task_tls( pxTCB );
|
|
}
|
|
|
|
static void * get_isr_tls( void )
|
|
{
|
|
/* In an ISR */
|
|
static int first = 1;
|
|
|
|
if( _Rarely( first ) )
|
|
{
|
|
first = 0;
|
|
__mw_run_tls_ctor(); /* Run constructors */
|
|
}
|
|
|
|
return ( void * ) _ftls;
|
|
}
|
|
#pragma off_inline(get_isr_tls)
|
|
|
|
static void * get_task_tls( void )
|
|
{
|
|
TaskHandle_t cur_task;
|
|
|
|
cur_task = xTaskGetCurrentTaskHandle();
|
|
|
|
if( cur_task == NULL )
|
|
{
|
|
return get_isr_tls();
|
|
}
|
|
|
|
void * tls = pvTaskGetThreadLocalStoragePointer( cur_task, 0 );
|
|
|
|
if( tls == NULL )
|
|
{
|
|
tls = init_task_tls();
|
|
|
|
if( tls )
|
|
{
|
|
vTaskSetThreadLocalStoragePointer( cur_task, 0, tls );
|
|
}
|
|
else
|
|
{
|
|
tls = get_isr_tls();
|
|
}
|
|
}
|
|
|
|
return tls;
|
|
}
|
|
#pragma off_inline(get_task_tls)
|
|
|
|
#if _ARC /* for ARC XCALLs need to preserve flags */
|
|
extern void * _Preserve_flags _mwget_tls( void );
|
|
#endif
|
|
|
|
/*
|
|
* Back end gens calls to find local data for this task
|
|
*/
|
|
void * _mwget_tls( void )
|
|
{
|
|
if( _ftls == ( char * ) 0 )
|
|
{
|
|
executable_requires_tls_section();
|
|
}
|
|
|
|
if( exc_nest_count > 0 ) /* In ISR */
|
|
{
|
|
return get_isr_tls();
|
|
}
|
|
else /* In Task */
|
|
{
|
|
return get_task_tls();
|
|
}
|
|
}
|
|
|
|
|
|
/* simple interface of thread safe */
|
|
typedef xSemaphoreHandle _lock_t;
|
|
#if configUSE_RECURSIVE_MUTEXES != 1
|
|
#error "configUSE_RECURSIVE_MUTEXES in FreeRTOSConfig.h need to 1"
|
|
#endif
|
|
|
|
void _mwmutex_create( _lock_t * mutex_ptr )
|
|
{
|
|
*mutex_ptr = xSemaphoreCreateRecursiveMutex();
|
|
}
|
|
|
|
void _mwmutex_delete( _lock_t * mutex_ptr )
|
|
{
|
|
if( ( *mutex_ptr ) != NULL )
|
|
{
|
|
vSemaphoreDelete( *mutex_ptr );
|
|
}
|
|
}
|
|
|
|
void _mwmutex_lock( _lock_t mutex )
|
|
{
|
|
if( ( mutex ) != NULL )
|
|
{
|
|
while( xSemaphoreTakeRecursive( mutex, portMAX_DELAY ) != pdTRUE )
|
|
{
|
|
}
|
|
}
|
|
}
|
|
|
|
void _mwmutex_unlock( _lock_t mutex )
|
|
{
|
|
if( ( mutex ) != NULL )
|
|
{
|
|
xSemaphoreGiveRecursive( mutex );
|
|
}
|
|
}
|
|
|
|
#else /* if defined( __MW__ ) */
|
|
|
|
#endif /* __MW__ */
|