diff --git a/History.txt b/History.txt index 9535f998f..5f145f9de 100644 --- a/History.txt +++ b/History.txt @@ -1,6 +1,6 @@ Documentation and download available at https://www.FreeRTOS.org/ -Changes between FreeRTOS V10.4.0 and FreeRTOS V10.3.1 released September 1 2020 +Changes between FreeRTOS V10.3.1 and FreeRTOS V10.4.0 released September 10 2020 See https://www.FreeRTOS.org/FreeRTOS-V10.4.x.html diff --git a/portable/ThirdParty/GCC/ARC_EM_HS/arc_freertos_exceptions.c b/portable/ThirdParty/GCC/ARC_EM_HS/arc_freertos_exceptions.c index 40e6fc51c..e414e0fc0 100644 --- a/portable/ThirdParty/GCC/ARC_EM_HS/arc_freertos_exceptions.c +++ b/portable/ThirdParty/GCC/ARC_EM_HS/arc_freertos_exceptions.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel V10.4.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * 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 diff --git a/portable/ThirdParty/GCC/ARC_EM_HS/arc_freertos_exceptions.h b/portable/ThirdParty/GCC/ARC_EM_HS/arc_freertos_exceptions.h index ffd15a049..f8668f554 100644 --- a/portable/ThirdParty/GCC/ARC_EM_HS/arc_freertos_exceptions.h +++ b/portable/ThirdParty/GCC/ARC_EM_HS/arc_freertos_exceptions.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel V10.4.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * 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 diff --git a/portable/ThirdParty/GCC/ARC_EM_HS/arc_support.s b/portable/ThirdParty/GCC/ARC_EM_HS/arc_support.s index 12b90d673..9c3daca5d 100644 --- a/portable/ThirdParty/GCC/ARC_EM_HS/arc_support.s +++ b/portable/ThirdParty/GCC/ARC_EM_HS/arc_support.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * 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 diff --git a/portable/ThirdParty/GCC/ARC_EM_HS/freertos_tls.c b/portable/ThirdParty/GCC/ARC_EM_HS/freertos_tls.c index b8b5a02a5..e92885f01 100644 --- a/portable/ThirdParty/GCC/ARC_EM_HS/freertos_tls.c +++ b/portable/ThirdParty/GCC/ARC_EM_HS/freertos_tls.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel V10.4.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * 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 diff --git a/portable/ThirdParty/GCC/ARC_EM_HS/port.c b/portable/ThirdParty/GCC/ARC_EM_HS/port.c index ad4360963..c587f7948 100644 --- a/portable/ThirdParty/GCC/ARC_EM_HS/port.c +++ b/portable/ThirdParty/GCC/ARC_EM_HS/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel V10.4.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * 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 diff --git a/portable/ThirdParty/GCC/ARC_EM_HS/portmacro.h b/portable/ThirdParty/GCC/ARC_EM_HS/portmacro.h index d5000ce51..886bd45dc 100644 --- a/portable/ThirdParty/GCC/ARC_EM_HS/portmacro.h +++ b/portable/ThirdParty/GCC/ARC_EM_HS/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel V10.4.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * 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 diff --git a/portable/ThirdParty/GCC/ARC_v1/arc_freertos_exceptions.c b/portable/ThirdParty/GCC/ARC_v1/arc_freertos_exceptions.c new file mode 100644 index 000000000..6d7c857c4 --- /dev/null +++ b/portable/ThirdParty/GCC/ARC_v1/arc_freertos_exceptions.c @@ -0,0 +1,51 @@ +/* + * FreeRTOS Kernel V10.2.1 + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/** + * \file + * \brief exception processing for freertos + */ + +/* #include "embARC.h" */ + +#include "arc_freertos_exceptions.h" + +#ifdef __GNU__ + extern void gnu_printf_setup( void ); +#endif + +/** + * \brief freertos related cpu exception initialization, all the interrupts handled by freertos must be not + * fast irqs. If fiq is needed, please install the default firq_exc_entry or your own fast irq entry into + * the specific interrupt exception. + */ +void freertos_exc_init( void ) +{ + #ifdef __GNU__ + gnu_printf_setup(); + #endif +} diff --git a/portable/ThirdParty/GCC/ARC_v1/arc_freertos_exceptions.h b/portable/ThirdParty/GCC/ARC_v1/arc_freertos_exceptions.h new file mode 100644 index 000000000..7264361d9 --- /dev/null +++ b/portable/ThirdParty/GCC/ARC_v1/arc_freertos_exceptions.h @@ -0,0 +1,45 @@ +/* + * FreeRTOS Kernel V10.2.1 + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef ARC_FREERTOS_EXCEPTIONS_H +#define ARC_FREERTOS_EXCEPTIONS_H + +/* + * here, all arc cpu exceptions share the same entry, also for all interrupt + * exceptions + */ +extern void exc_entry_cpu( void ); /* cpu exception entry for freertos */ +extern void exc_entry_int( void ); /* int exception entry for freertos */ + +/* task dispatch functions in .s */ +extern void start_r( void ); +extern void start_dispatch(); +extern void dispatch(); + +extern void freertos_exc_init( void ); + +#endif /* ARC_FREERTOS_EXCEPTIONS_H */ diff --git a/portable/ThirdParty/GCC/ARC_v1/arc_support.s b/portable/ThirdParty/GCC/ARC_v1/arc_support.s new file mode 100644 index 000000000..a5f9d6a42 --- /dev/null +++ b/portable/ThirdParty/GCC/ARC_v1/arc_support.s @@ -0,0 +1,321 @@ +/* + * FreeRTOS Kernel V10.2.1 + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/** + * \file + * \ingroup OS_FREERTOS + * \brief freertos support for arc processor + * like task dispatcher, interrupt handler + */ +/** @cond OS_FREERTOS_ASM_ARC_SUPPORT */ + +/* + * core-dependent part in assemble language (for arc) + */ +#define __ASSEMBLY__ +#include "arc/arc.h" +#include "arc/arc_asm_common.h" + +/* + * task dispatcher + * + */ + .text + .align 4 + .global dispatch +dispatch: +/* + * the pre-conditions of this routine are task context, CPU is + * locked, dispatch is enabled. + */ + SAVE_NONSCRATCH_REGS /* save callee save registers */ + mov r1, dispatch_r + PUSH r1 /* save return address */ + ld r0, [pxCurrentTCB] + bl dispatcher + +/* return routine when task dispatch happened in task context */ +dispatch_r: + RESTORE_NONSCRATCH_REGS /* recover registers */ + j [blink] + +/* + * start dispatch + */ + .global start_dispatch + .align 4 +start_dispatch: +/* + * this routine is called in the non-task context during the startup of the kernel + * , and all the interrupts are locked. + * + * when the dispatcher is called, the cpu is locked, no nest exception (CPU exception/interrupt). + * In target_initialize, all interrupt priority mask should be cleared, cpu should be + * locked, the interrupts outside the kernel such as fiq can be + * enabled. + */ + clri + mov r0, 0 + st r0, [exc_nest_count] + b dispatcher_0 +/* + * dispatcher + */ +dispatcher: + ld r1, [ulCriticalNesting] + PUSH r1 /* save critical nesting */ + st sp, [r0] /* save stack pointer of current task, r0->pxCurrentTCB */ + jl vTaskSwitchContext /* change the value of pxCurrentTCB */ +/* + * before dispatcher is called, task context | cpu locked | dispatch enabled + * should be satisfied. In this routine, the processor will jump + * into the entry of next to run task + * + * i.e. kernel mode, IRQ disabled, dispatch enabled + */ +dispatcher_0: + ld r1, [pxCurrentTCB] + ld sp, [r1] /* recover task stack */ +#if ARC_FEATURE_STACK_CHECK + lr r0, [AUX_STATUS32] + bclr r0, r0, AUX_STATUS_BIT_SC + flag r0 + jl vPortSetStackCheck + lr r0, [AUX_STATUS32] + bset r0, r0, AUX_STATUS_BIT_SC + flag r0 +#endif + POP r0 /* get critical nesting */ + st r0, [ulCriticalNesting] + POP r0 /* get return address */ + j [r0] + +/* + * task startup routine + * + */ + .text + .global start_r + .align 4 +start_r: + seti /* unlock cpu */ + mov blink, vPortEndTask /* set return address */ + POP r1 /* get task function body */ + POP r0 /* get task parameters */ + j [r1] + +/****** exceptions and interrupts handing ******/ +/****** entry for exception handling ******/ + .global exc_entry_cpu + .align 4 +exc_entry_cpu: + + EXCEPTION_PROLOGUE + + + mov blink, sp + mov r3, sp /* as exception handler's para(p_excinfo) */ + + ld r1, [exc_nest_count] + add r1, r1, 1 + st r1, [exc_nest_count] + brne r1, 0, exc_handler_1 +/* change to exception stack if interrupt happened in task context */ + mov sp, _e_stack +exc_handler_1: + PUSH blink + +/* find the exception cause */ +#if ARC_FEATURE_CORE_700 + lr r0, [AUX_ECR] + lsr r0, r0, 16 + bmsk r0, r0, 7 +#endif + mov r1, exc_int_handler_table + ld.as r2, [r1, r0] + + mov r0, r3 + jl [r2] /* !!!!jump to exception handler where interrupts are not allowed! */ + +/* interrupts are not allowed */ +ret_exc: + POP sp + mov r1, exc_nest_count + ld r0, [r1] + sub r0, r0, 1 + st r0, [r1] + brne r0, 0, ret_exc_1 /* nested exception case */ + lr r1, [AUX_IRQ_LV12] + brne r1, 0, ret_exc_1 /* nested or pending interrupt case */ + + ld r0, [context_switch_reqflg] + brne r0, 0, ret_exc_2 +ret_exc_1: /* return from non-task context, interrupts or exceptions are nested */ + + EXCEPTION_EPILOGUE +#if ARC_FEATURE_CORE_600 + rtie ilink2 +#else + rtie +#endif + +/* there is a dispatch request */ +ret_exc_2: + /* clear dispatch request */ + mov r0, 0 + st r0, [context_switch_reqflg] + + ld r0, [pxCurrentTCB] + breq r0, 0, ret_exc_1 + + SAVE_CALLEE_REGS /* save callee save registers */ + + lr r0, [AUX_STATUS32] + bclr r0, r0, AUX_STATUS_BIT_AE /* clear exception bit */ + flag r0 + + mov r1, ret_exc_r /* save return address */ + PUSH r1 + + bl dispatcher /* r0->pxCurrentTCB */ + +ret_exc_r: + /* recover exception status */ + lr r0, [AUX_STATUS32] + bset r0, r0, AUX_STATUS_BIT_AE + flag r0 + + RESTORE_CALLEE_REGS /* recover registers */ + EXCEPTION_EPILOGUE +#if ARC_FEATURE_CORE_600 + rtie ilink2 +#else + rtie +#endif + +/****** entry for normal interrupt exception handling ******/ + .global exc_entry_int /* entry for interrupt handling */ + .align 4 +exc_entry_int: + + INTERRUPT_PROLOGUE + + mov blink, sp + + /* disable interrupt */ + push r0 + lr r0, [AUX_STATUS32] + push r0 + bclr r0, r0, AUX_STATUS_BIT_E1 + bclr r0, r0, AUX_STATUS_BIT_E2 + flag r0 + ld r3, [exc_nest_count] + add r2, r3, 1 + st r2, [exc_nest_count] + /* enable interrupt */ + pop r0 + flag r0 + pop r0 + + brne r3, 0, irq_handler_1 +/* change to exception stack if interrupt happened in task context */ + mov sp, _e_stack +#if ARC_FEATURE_STACK_CHECK + lr r0, [AUX_STATUS32] + bclr r0, r0, AUX_STATUS_BIT_SC + flag r0 +#endif +irq_handler_1: + PUSH blink + +/* critical area */ +#if ARC_FEATURE_CORE_700 + lr r0, [AUX_IRQ_CAUSE1] +#endif + mov r1, exc_int_handler_table + ld.as r2, [r1, r0] /* r2 = exc_int_handler_table + irqno *4 */ +/* handle software triggered interrupt */ + lr r3, [AUX_IRQ_HINT] + cmp r3, r0 + bne.d irq_hint_handled + xor r3, r3, r3 + sr r3, [AUX_IRQ_HINT] +irq_hint_handled: + + jl [r2] /* jump to interrupt handler */ +/* no interrupts are allowed from here */ +ret_int: + clri /* disable interrupt */ + + POP sp + mov r1, exc_nest_count + ld r0, [r1] + sub r0, r0, 1 + st r0, [r1] +/* if there are multi-bits set in IRQ_LV12, it's still in nest interrupt */ + lr r1, [AUX_IRQ_LV12] + + ld r0, [context_switch_reqflg] + brne r0, 0, ret_int_2 +ret_int_1: /* return from non-task context */ + INTERRUPT_EPILOGUE +#if ARC_FEATURE_CORE_600 +/* TODO: series 600 IRQ6 and IRQ7 uses ilink2 */ + rtie ilink1 +#else + rtie +#endif +/* there is a dispatch request */ +ret_int_2: + /* clear dispatch request */ + mov r0, 0 + st r0, [context_switch_reqflg] + + ld r0, [pxCurrentTCB] + breq r0, 0, ret_int_1 + +/* r1 has old AUX_IRQ_LV12 */ + PUSH r1 +/* clear related bits in IRQ_ACT manually to simulate a irq return */ + + SAVE_CALLEE_REGS /* save callee save registers */ + mov r1, ret_int_r /* save return address */ + PUSH r1 + + bl dispatcher /* r0->pxCurrentTCB */ + +ret_int_r: + RESTORE_CALLEE_REGS /* recover registers */ + POPAX AUX_IRQ_LV12 + INTERRUPT_EPILOGUE +#if ARC_FEATURE_CORE_600 + rtie ilink1 +#else + rtie +#endif + +/** @endcond */ diff --git a/portable/ThirdParty/GCC/ARC_v1/port.c b/portable/ThirdParty/GCC/ARC_v1/port.c new file mode 100644 index 000000000..fe831b1ef --- /dev/null +++ b/portable/ThirdParty/GCC/ARC_v1/port.c @@ -0,0 +1,295 @@ +/* + * FreeRTOS Kernel V10.2.1 + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * Implementation of functions defined in portable.h + */ + +#include "FreeRTOS.h" +#include "task.h" +#include "FreeRTOSConfig.h" + +#include "arc/arc_exception.h" +#include "arc/arc_timer.h" +#include "board.h" + +#include "arc_freertos_exceptions.h" + +volatile unsigned int ulCriticalNesting = 999UL; +volatile unsigned int context_switch_reqflg; /* task context switch request flag in exceptions and interrupts handling */ + +/** + * \var exc_nest_count + * \brief the counter for exc/int processing, =0 no int/exc + * >1 in int/exc processing + * @} + */ +uint32_t exc_nest_count; +/* --------------------------------------------------------------------------*/ + +/** + * @brief kernel tick interrupt handler of freertos + */ +/* ----------------------------------------------------------------------------*/ +static void vKernelTick( void * ptr ) +{ + /* clear timer interrupt */ + arc_timer_int_clear( BOARD_OS_TIMER_ID ); + board_timer_update( configTICK_RATE_HZ ); + + if( xTaskIncrementTick() ) + { + portYIELD_FROM_ISR(); /* need to make task switch */ + } +} + +/* --------------------------------------------------------------------------*/ + +/** + * @brief setup freertos kernel tick + */ +/* ----------------------------------------------------------------------------*/ +static void prvSetupTimerInterrupt( void ) +{ + unsigned int cyc = configCPU_CLOCK_HZ / configTICK_RATE_HZ; + + int_disable( BOARD_OS_TIMER_INTNO ); /* disable os timer interrupt */ + arc_timer_stop( BOARD_OS_TIMER_ID ); + arc_timer_start( BOARD_OS_TIMER_ID, TIMER_CTRL_IE | TIMER_CTRL_NH, cyc ); + + int_handler_install( BOARD_OS_TIMER_INTNO, ( INT_HANDLER_T ) vKernelTick ); + int_pri_set( BOARD_OS_TIMER_INTNO, INT_PRI_MIN ); + int_enable( BOARD_OS_TIMER_INTNO ); +} + +/* + * Setup the stack of a new task so it is ready to be placed under the + * scheduler control. The registers have to be placed on the stack in + * the order that the port expects to find them. + * + * For ARC, task context switch is implemented with the help of SWI exception + * It's not efficient but simple. + * + */ +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + TaskFunction_t pxCode, + void * pvParameters ) +{ + /* To ensure asserts in tasks.c don't fail, although in this case the assert + * is not really required. */ + pxTopOfStack--; + + /* Setup the initial stack of the task. The stack is set exactly as + * expected by the portRESTORE_CONTEXT() macro. */ + + /* When the task starts is will expect to find the function parameter in + * R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* function body */ + + /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) start_r; /* dispatch return address */ + + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portNO_CRITICAL_NESTING; + return pxTopOfStack; +} + +/* --------------------------------------------------------------------------*/ + +/** + * @brief start the freertos scheduler, go to the first task + * + * @returns + */ +/* ----------------------------------------------------------------------------*/ +BaseType_t xPortStartScheduler( void ) +{ + /* Start the timer that generates the tick ISR. */ + prvSetupTimerInterrupt(); + start_dispatch(); + + /* Should not get here! */ + return 0; +} + +/* --------------------------------------------------------------------------*/ + +/** + * @brief + */ +/* ----------------------------------------------------------------------------*/ +void vPortEndScheduler( void ) +{ +} + +/* --------------------------------------------------------------------------*/ + +/** + * @brief generate a task switch request in ISR + */ +/* ----------------------------------------------------------------------------*/ +void vPortYieldFromIsr( void ) +{ + unsigned int status32; + + status32 = cpu_lock_save(); + context_switch_reqflg = true; + cpu_unlock_restore( status32 ); +} + +/* --------------------------------------------------------------------------*/ + +/** + * @brief + */ +/* ----------------------------------------------------------------------------*/ +void vPortYield( void ) +{ + unsigned int status32; + + status32 = cpu_lock_save(); + dispatch(); + cpu_unlock_restore( status32 ); +} + +/* --------------------------------------------------------------------------*/ + +/** + * @brief + */ +/* ----------------------------------------------------------------------------*/ +void vPortEndTask( void ) +{ + #if ( INCLUDE_vTaskDelete == 1 ) + vTaskDelete( NULL ); /* Delete task itself */ + #endif + + while( 1 ) /* Yield to other task */ + { + vPortYield(); + } +} + +#if ARC_FEATURE_STACK_CHECK + +/* + * !!! Note !!! + * This a trick!!! + * It's a copy from task.c. We need to konw the definition of TCB for the purpose of hardware + * stack check. Pls don't forget to update it when FreeRTOS is updated. + */ + typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. */ + { + volatile StackType_t * pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */ + #endif + + ListItem_t xStateListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */ + ListItem_t xEventListItem; /*< Used to reference a task from an event list. */ + UBaseType_t uxPriority; /*< The priority of the task. 0 is the lowest priority. */ + StackType_t * pxStack; /*< Points to the start of the stack. */ + char pcTaskName[ configMAX_TASK_NAME_LEN ]; /*< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + + #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) + StackType_t * pxEndOfStack; /*< Points to the highest valid address for the stack. */ + #endif + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */ + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */ + UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */ + #endif + + #if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */ + UBaseType_t uxMutexesHeld; + #endif + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + TaskHookFunction_t pxTaskTag; + #endif + + #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + void * pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + uint32_t ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */ + #endif + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + + /* Allocate a Newlib reent structure that is specific to this task. + * Note Newlib support has been included by popular demand, but is not + * used by the FreeRTOS maintainers themselves. FreeRTOS is not + * responsible for resulting newlib operation. User must be familiar with + * newlib and must provide system-wide implementations of the necessary + * stubs. Be warned that (at the time of writing) the current newlib design + * implements a system-wide malloc() that must be provided with locks. */ + struct _reent xNewLib_reent; + #endif + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + volatile uint32_t ulNotifiedValue; + volatile uint8_t ucNotifyState; + #endif + + /* See the comments above the definition of + * tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */ + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */ + #endif + + #if ( INCLUDE_xTaskAbortDelay == 1 ) + uint8_t ucDelayAborted; + #endif + + #if ( configUSE_POSIX_ERRNO == 1 ) + int iTaskErrno; + #endif + } tskTCB; + + + void vPortSetStackCheck( TaskHandle_t old, + TaskHandle_t new ) + { + if( new != NULL ) + { + arc_aux_write( AUX_USTACK_BASE, ( uint32_t ) ( new->pxEndOfStack ) ); + arc_aux_write( AUX_USTACK_TOP, ( uint32_t ) ( new->pxStack ) ); + } + } +#endif /* if ARC_FEATURE_STACK_CHECK */ diff --git a/portable/ThirdParty/GCC/ARC_v1/portmacro.h b/portable/ThirdParty/GCC/ARC_v1/portmacro.h new file mode 100644 index 000000000..dec26c383 --- /dev/null +++ b/portable/ThirdParty/GCC/ARC_v1/portmacro.h @@ -0,0 +1,149 @@ +/* + * FreeRTOS Kernel V10.2.1 + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef PORTMACRO_H + #define PORTMACRO_H + #include "embARC.h" + + #ifdef __cplusplus + extern "C" { + #endif + +/* record stack high address for stack check */ + #ifndef configRECORD_STACK_HIGH_ADDRESS + #define configRECORD_STACK_HIGH_ADDRESS 1 + #endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ + #define portCHAR char + #define portFLOAT float + #define portDOUBLE double + #define portLONG long + #define portSHORT short + #define portSTACK_TYPE unsigned int + #define portBASE_TYPE portLONG + + #ifndef Asm + #define Asm __asm__ volatile + #endif + +/* + * normal constants + */ + #ifndef NULL + #define NULL 0 /* invalid pointer */ + #endif /* NULL */ + + #ifndef true + #define true 1 /* true */ + #endif /* true */ + + #ifndef false + #define false 0 /* false */ + #endif /* false */ + + typedef portSTACK_TYPE StackType_t; + typedef long BaseType_t; + typedef unsigned long UBaseType_t; + + #if ( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff + #else + typedef unsigned int TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #endif + + #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) + #define portSTACK_GROWTH ( -1 ) + #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) + #define portBYTE_ALIGNMENT 8 + #define portNOP() Asm( "nop_s" ); + #define IPM_ENABLE_ALL 1 + + #define portYIELD_FROM_ISR() vPortYieldFromIsr() + #define portYIELD() vPortYield() + +/* Critical section management. */ + #define portDISABLE_INTERRUPTS() \ + { \ + arc_lock(); \ + } \ + + #define portENABLE_INTERRUPTS() \ + { \ + arc_unlock(); \ + } \ + + extern volatile unsigned int ulCriticalNesting; + + #define portENTER_CRITICAL() \ + { \ + portDISABLE_INTERRUPTS() \ + ulCriticalNesting++; \ + } + + + #define portEXIT_CRITICAL() \ + { \ + if( ulCriticalNesting > portNO_CRITICAL_NESTING ) \ + { \ + ulCriticalNesting--; \ + if( ulCriticalNesting == portNO_CRITICAL_NESTING ) \ + { \ + portENABLE_INTERRUPTS() \ + } \ + } \ + } + + + #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) + #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) + + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() do {} while( 0 ) /* we use the timer */ + #define portALT_GET_RUN_TIME_COUNTER_VALUE( dest ) ( dest = xTickCount ) + + #define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB + + void vPortYield( void ); + void vPortYieldFromIsr( void ); + + #ifdef __cplusplus +} + #endif + +#endif /* PORTMACRO_H */ diff --git a/portable/ThirdParty/GCC/ARM_CM33_TFM/README.md b/portable/ThirdParty/GCC/ARM_CM33_TFM/README.md new file mode 100644 index 000000000..6b03f5624 --- /dev/null +++ b/portable/ThirdParty/GCC/ARM_CM33_TFM/README.md @@ -0,0 +1,71 @@ +# Target of this port + +This port adds the support that FreeRTOS applications can call the secure +services in Trusted Firmware M(TF-M) through Platform Security Architecture +(PSA) API based on the ARM Cortex-M33 platform. + +The Platform Security Architecture (PSA) makes it quicker, easier and cheaper +to design security into a device from the ground up. PSA is made up of four key +stages: analyze, architect, implement, and certify. See [PSA Resource Page](https://developer.arm.com/architectures/security-architectures/platform-security-architecture). + +TF-M is an open source project. It provides a reference implementation of PSA +for Arm M-profile architecture. Please get the details from this [link](https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/about/). + +# Derivation of the source code + +* ```os_wrapper_freertos.c``` + The implementation of APIs which are defined in ```os_wrapper\mutex.h``` by TF-M + (tag: TF-Mv1.1). The implementation is based on FreeRTOS mutex type semaphore. + +# Usage notes + +To build a project based on this port: +* Step 1: build the secure image. Please follow the **Build the Secure Side** section for details. +* Step 2: build the nonsecure image. Please follow the **Build the Non-Secure Side** for details. + +## Build the Secure Side + +### Get the TF-M source code + +See the [link](https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/) to get the source code. This port is based on TF-M version **tag: TF-Mv1.1**. + +### Build TF-M + +Please refer to this [link](https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/tree/docs/getting_started/tfm_build_instruction.rst) to build the secure side. +_**Note:** ```CONFIG_TFM_ENABLE_CTX_MGMT``` must be configured as "OFF" when building TF-M_. + +## Build the Non-Secure Side + +Please copy all the files in ```freertos_kernel\portable\GCC\ARM_CM33_NTZ``` into the ```freertos_kernel\portable\GCC\ARM_CM33_TFM``` folder before using this port. Note that TrustZone is enabled in this port. The TF-M runs in the Secure Side. + +Please call the API ```tfm_ns_interface_init()``` which is defined in ```os_wrapper_freertos.c``` at the very beginning of your application. Otherwise, it will always fail when calling a TF-M service in the Nonsecure Side. + +### Configuration in FreeRTOS kernel + +* ```configRUN_FREERTOS_SECURE_ONLY``` +This macro should be configured as 0. In this port, TF-M runs in the Secure Side while FreeRTOS +Kernel runs in the Non-Secure Side. + +* ```configENABLE_FPU``` +The setting of this macro is decided by the setting in Secure Side which is platform-specific. +If the Secure Side enables Non-Secure access to FPU, then this macro can be configured as 0 or 1. Otherwise, this macro can only be configured as 0. + +* ```configENABLE_TRUSTZONE``` +This macro should be configured as 0 because TF-M doesn't use the secure context management function of FreeRTOS. New secure context management might be introduced when TF-M supports multiple secure context. + + +### Integrate TF-M Non-Secure interface with FreeRTOS project + +To enable calling TF-M services by the Non-Secure Side, the files below should be included in the FreeRTOS project and built together. +* files in ```trusted-firmware-m\build\install\export\tfm\src``` + These files contain the implementation of PSA Functional Developer APIs which can be called by Non-Secure Side directly and PSA Firmware Framework APIs in the IPC model. These files should be taken + as part of the Non-Secure source code. +* files in ```trusted-firmware-m\build\install\export\tfm\include``` + These files are the necessary header files to call TF-M services. +* ```trusted-firmware-m\build\install\export\tfm\veneers\s_veneers.o``` + This object file contains all the Non-Secure callable functions exported by + TF-M and it should be linked when generating the Non-Secure image. + + + +*Copyright (c) 2020, Arm Limited. All rights reserved.* diff --git a/portable/ThirdParty/GCC/ARM_CM33_TFM/os_wrapper_freertos.c b/portable/ThirdParty/GCC/ARM_CM33_TFM/os_wrapper_freertos.c new file mode 100644 index 000000000..5e9145b08 --- /dev/null +++ b/portable/ThirdParty/GCC/ARM_CM33_TFM/os_wrapper_freertos.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. 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. + * + */ + +/* + * This file contains the implementation of APIs which are defined in + * os_wrapper/mutex.h by TF-M(tag: TF-Mv1.1). The implementation is based + * on FreeRTOS mutex type semaphore. + */ + +#include "os_wrapper/mutex.h" + +#include "FreeRTOS.h" +#include "semphr.h" +#include "mpu_wrappers.h" + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + /* + * In the static allocation, the RAM is required to hold the semaphore's + * state. + */ + StaticSemaphore_t xSecureMutexBuffer; +#endif + +void * os_wrapper_mutex_create( void ) +{ +SemaphoreHandle_t xMutexHandle = NULL; + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + xMutexHandle = xSemaphoreCreateMutex(); +#elif( configSUPPORT_STATIC_ALLOCATION == 1 ) + xMutexHandle = xSemaphoreCreateMutexStatic( &xSecureMutexBuffer ); +#endif + return ( void * ) xMutexHandle; +} +/*-----------------------------------------------------------*/ + +uint32_t os_wrapper_mutex_acquire( void * handle, uint32_t timeout ) +{ +BaseType_t xRet; + + if( ! handle ) + return OS_WRAPPER_ERROR; + + xRet = xSemaphoreTake( ( SemaphoreHandle_t ) handle, + ( timeout == OS_WRAPPER_WAIT_FOREVER ) ? + portMAX_DELAY : ( TickType_t ) timeout ); + + if( xRet != pdPASS ) + return OS_WRAPPER_ERROR; + else + return OS_WRAPPER_SUCCESS; +} +/*-----------------------------------------------------------*/ + +uint32_t os_wrapper_mutex_release( void * handle ) +{ +BaseType_t xRet; + + if( !handle ) + return OS_WRAPPER_ERROR; + + xRet = xSemaphoreGive( ( SemaphoreHandle_t ) handle ); + + if( xRet != pdPASS ) + return OS_WRAPPER_ERROR; + else + return OS_WRAPPER_SUCCESS; +} +/*-----------------------------------------------------------*/ + +uint32_t os_wrapper_mutex_delete( void * handle ) +{ + vSemaphoreDelete( ( SemaphoreHandle_t ) handle ); + + return OS_WRAPPER_SUCCESS; +} +/*-----------------------------------------------------------*/ diff --git a/portable/ThirdParty/GCC/Posix/FreeRTOS-simulator-for-Linux.url b/portable/ThirdParty/GCC/Posix/FreeRTOS-simulator-for-Linux.url new file mode 100644 index 000000000..60f7ee8c3 --- /dev/null +++ b/portable/ThirdParty/GCC/Posix/FreeRTOS-simulator-for-Linux.url @@ -0,0 +1,5 @@ +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 +[InternetShortcut] +IDList= +URL=https://www.freertos.org/FreeRTOS-simulator-for-Linux.html diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c index c2eddc54e..2f81ed8cb 100644 --- a/portable/ThirdParty/GCC/Posix/port.c +++ b/portable/ThirdParty/GCC/Posix/port.c @@ -33,8 +33,8 @@ * running are blocked in sigwait(). * * Task switch is done by resuming the thread for the next task by - * sending it the resume signal (SIGUSR1) and then suspending the - * current thread. + * signaling the condition variable and then waiting on a condition variable + * with the current thread. * * The timer interrupt uses SIGALRM and care is taken to ensure that * the signal handler runs only on the thread for the current task. @@ -44,9 +44,6 @@ * deadlocks as the FreeRTOS kernel can switch tasks while they're * holding a pthread mutex. * - * Replacement malloc(), free(), calloc(), and realloc() are provided - * for glibc (see below for more information). - * * stdio (printf() and friends) should be called from a single task * only or serialized with a FreeRTOS primitive such as a binary * semaphore or mutex. @@ -65,6 +62,7 @@ /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" +#include "utils/wait_for_event.h" /*-----------------------------------------------------------*/ #define SIG_RESUME SIGUSR1 @@ -75,6 +73,7 @@ typedef struct THREAD pdTASK_CODE pxCode; void *pvParams; BaseType_t xDying; + struct event *ev; } Thread_t; /* @@ -104,82 +103,14 @@ static portBASE_TYPE xSchedulerEnd = pdFALSE; static void prvSetupSignalsAndSchedulerPolicy( void ); static void prvSetupTimerInterrupt( void ); static void *prvWaitForStart( void * pvParams ); -static void prvSwitchThread( Thread_t *xThreadToResume, Thread_t *xThreadToSuspend ); -static void prvSuspendSelf( void ); -static void prvResumeThread( pthread_t xThreadId ); +static void prvSwitchThread( Thread_t * xThreadToResume, + Thread_t *xThreadToSuspend ); +static void prvSuspendSelf( Thread_t * thread); +static void prvResumeThread( Thread_t * xThreadId ); static void vPortSystemTickHandler( int sig ); static void vPortStartFirstTask( void ); /*-----------------------------------------------------------*/ -/* - * The standard glibc malloc(), free() etc. take an internal lock so - * it is not safe to switch tasks while calling them. - * - * Requiring the application use the safe xPortMalloc() and - * vPortFree() is not sufficient as malloc() is used internally by - * glibc (e.g., by strdup() and the pthread library.) - * - * To further complicate things malloc() and free() may be called - * outside of task context during pthread destruction so using - * vTaskSuspend() and xTaskResumeAll() cannot be used. - * vPortEnterCritical() and vPortExitCritical() cannot be used either - * as they use global state for the critical section nesting (this - * cannot be fixed by using TLS as pthread destruction needs to free - * the TLS). - * - * Explicitly save/disable and restore the signal mask to block the - * timer (SIGALRM) and other signals. - */ - -extern void *__libc_malloc(size_t); -extern void __libc_free(void *); -extern void *__libc_calloc(size_t, size_t); -extern void *__libc_realloc(void *ptr, size_t); - -void *malloc(size_t size) -{ -sigset_t xSavedSignals; -void *ptr; - - pthread_sigmask( SIG_BLOCK, &xAllSignals, &xSavedSignals ); - ptr = __libc_malloc( size ); - pthread_sigmask( SIG_SETMASK, &xSavedSignals, NULL ); - - return ptr; -} - -void free(void *ptr) -{ -sigset_t xSavedSignals; - - pthread_sigmask( SIG_BLOCK, &xAllSignals, &xSavedSignals ); - __libc_free( ptr ); - pthread_sigmask( SIG_SETMASK, &xSavedSignals, NULL ); -} - -void *calloc(size_t nmemb, size_t size) -{ -sigset_t xSavedSignals; -void *ptr; - - pthread_sigmask( SIG_BLOCK, &xAllSignals, &xSavedSignals ); - ptr = __libc_calloc( nmemb, size ); - pthread_sigmask( SIG_SETMASK, &xSavedSignals, NULL ); - - return ptr; -} - -void *realloc(void *ptr, size_t size) -{ -sigset_t xSavedSignals; - - pthread_sigmask( SIG_BLOCK, &xAllSignals, &xSavedSignals ); - ptr = __libc_realloc( ptr, size ); - pthread_sigmask( SIG_SETMASK, &xSavedSignals, NULL ); - - return ptr; -} - static void prvFatalError( const char *pcCall, int iErrno ) { fprintf( stderr, "%s: %s\n", pcCall, strerror( iErrno ) ); @@ -214,6 +145,8 @@ int iRet; pthread_attr_init( &xThreadAttributes ); pthread_attr_setstack( &xThreadAttributes, pxEndOfStack, ulStackSize ); + thread->ev = event_create(); + vPortEnterCritical(); iRet = pthread_create( &thread->pthread, &xThreadAttributes, @@ -234,7 +167,7 @@ void vPortStartFirstTask( void ) Thread_t *pxFirstThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() ); /* Start the first task. */ - prvResumeThread( pxFirstThread->pthread ); + prvResumeThread( pxFirstThread ); } /*-----------------------------------------------------------*/ @@ -248,8 +181,8 @@ sigset_t xSignals; hMainThread = pthread_self(); - /* Start the timer that generates the tick ISR. Interrupts are disabled - here already. */ + /* Start the timer that generates the tick ISR(SIGALRM). + Interrupts are disabled here already. */ prvSetupTimerInterrupt(); /* Start the first task. */ @@ -275,6 +208,7 @@ void vPortEndScheduler( void ) { struct itimerval itimer; struct sigaction sigtick; +Thread_t *xCurrentThread; /* Stop the timer and ignore any pending SIGALRMs that would end * up running on the main thread when it is resumed. */ @@ -282,19 +216,20 @@ struct sigaction sigtick; itimer.it_value.tv_usec = 0; itimer.it_interval.tv_sec = 0; - itimer.it_interval.tv_usec = 0; + itimer.it_interval.tv_usec = 0; (void)setitimer( ITIMER_REAL, &itimer, NULL ); sigtick.sa_flags = 0; sigtick.sa_handler = SIG_IGN; - sigemptyset( &sigtick.sa_mask ); + sigemptyset( &sigtick.sa_mask ); sigaction( SIGALRM, &sigtick, NULL ); /* Signal the scheduler to exit its loop. */ xSchedulerEnd = pdTRUE; (void)pthread_kill( hMainThread, SIG_RESUME ); - prvSuspendSelf(); + xCurrentThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() ); + prvSuspendSelf(xCurrentThread); } /*-----------------------------------------------------------*/ @@ -425,16 +360,21 @@ uint64_t xExpectedTicks; uxCriticalNesting++; /* Signals are blocked in this signal handler. */ +#if ( configUSE_PREEMPTION == 1 ) pxThreadToSuspend = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() ); +#endif /* Tick Increment, accounting for any lost signals or drift in * the timer. */ - xExpectedTicks = (prvGetTimeNs() - prvStartTimeNs) - / (portTICK_RATE_MICROSECONDS * 1000); - do { +/* + * Comment code to adjust timing according to full demo requirements + * xExpectedTicks = (prvGetTimeNs() - prvStartTimeNs) + * / (portTICK_RATE_MICROSECONDS * 1000); + * do { */ xTaskIncrementTick(); - prvTickCount++; - } while (prvTickCount < xExpectedTicks); +/* prvTickCount++; + * } while (prvTickCount < xExpectedTicks); +*/ #if ( configUSE_PREEMPTION == 1 ) /* Select Next Task. */ @@ -461,8 +401,7 @@ void vPortCancelThread( void *pxTaskToDelete ) Thread_t *pxThreadToCancel = prvGetThreadFromTask( pxTaskToDelete ); /* - * The thread has already been suspended so it can be safely - * cancelled. + * The thread has already been suspended so it can be safely cancelled. */ pthread_cancel( pxThreadToCancel->pthread ); pthread_join( pxThreadToCancel->pthread, NULL ); @@ -473,7 +412,7 @@ static void *prvWaitForStart( void * pvParams ) { Thread_t *pxThread = pvParams; - prvSuspendSelf(); + prvSuspendSelf(pxThread); /* Resumed for the first time, unblocks all signals. */ uxCriticalNesting = 0; @@ -502,24 +441,25 @@ BaseType_t uxSavedCriticalNesting; */ uxSavedCriticalNesting = uxCriticalNesting; - prvResumeThread( pxThreadToResume->pthread ); + prvResumeThread( pxThreadToResume ); if ( pxThreadToSuspend->xDying ) { + event_delete(pxThreadToSuspend->ev); pthread_exit( NULL ); } - prvSuspendSelf(); + prvSuspendSelf( pxThreadToSuspend ); uxCriticalNesting = uxSavedCriticalNesting; } } /*-----------------------------------------------------------*/ -static void prvSuspendSelf( void ) +static void prvSuspendSelf( Thread_t *thread ) { int iSig; /* - * Suspend this thread by waiting for a SIG_RESUME signal. + * Suspend this thread by waiting for a pthread_cond_signal event. * * A suspended thread must not handle signals (interrupts) so * all signals must be blocked by calling this from: @@ -530,17 +470,17 @@ int iSig; * - From a signal handler that has all signals masked. * * - A thread with all signals blocked with pthread_sigmask(). - */ - sigwait( &xResumeSignals, &iSig ); + */ + event_wait(thread->ev); } /*-----------------------------------------------------------*/ -static void prvResumeThread( pthread_t xThreadId ) +static void prvResumeThread( Thread_t *xThreadId ) { - if ( pthread_self() != xThreadId ) + if ( pthread_self() != xThreadId->pthread ) { - pthread_kill( xThreadId, SIG_RESUME ); + event_signal(xThreadId->ev); } } /*-----------------------------------------------------------*/ diff --git a/portable/ThirdParty/GCC/Posix/utils/wait_for_event.c b/portable/ThirdParty/GCC/Posix/utils/wait_for_event.c new file mode 100644 index 000000000..896604a53 --- /dev/null +++ b/portable/ThirdParty/GCC/Posix/utils/wait_for_event.c @@ -0,0 +1,76 @@ +#include +#include +#include + +#include "wait_for_event.h" + +struct event +{ + pthread_mutex_t mutex; + pthread_cond_t cond; + bool event_triggered; +}; + +struct event * event_create() +{ + struct event * ev = malloc( sizeof( struct event ) ); + + ev->event_triggered = false; + pthread_mutex_init( &ev->mutex, NULL ); + pthread_cond_init( &ev->cond, NULL ); + return ev; +} + +void event_delete( struct event * ev ) +{ + pthread_mutex_destroy( &ev->mutex ); + pthread_cond_destroy( &ev->cond ); + free( ev ); +} + +bool event_wait( struct event * ev ) +{ + pthread_mutex_lock( &ev->mutex ); + + while( ev->event_triggered == false ) + { + pthread_cond_wait( &ev->cond, &ev->mutex ); + } + + ev->event_triggered = false; + pthread_mutex_unlock( &ev->mutex ); + return true; +} +bool event_wait_timed( struct event * ev, + time_t ms ) +{ + struct timespec ts; + int ret = 0; + + clock_gettime( CLOCK_REALTIME, &ts ); + //ts.tv_sec += ms; + ts.tv_nsec += (ms * 1000000); + pthread_mutex_lock( &ev->mutex ); + + while( (ev->event_triggered == false) && (ret == 0) ) + { + ret = pthread_cond_timedwait( &ev->cond, &ev->mutex, &ts ); + + if( ( ret == -1 ) && ( errno == ETIMEDOUT ) ) + { + return false; + } + } + + ev->event_triggered = false; + pthread_mutex_unlock( &ev->mutex ); + return true; +} + +void event_signal( struct event * ev ) +{ + pthread_mutex_lock( &ev->mutex ); + ev->event_triggered = true; + pthread_cond_signal( &ev->cond ); + pthread_mutex_unlock( &ev->mutex ); +} diff --git a/portable/ThirdParty/GCC/Posix/utils/wait_for_event.h b/portable/ThirdParty/GCC/Posix/utils/wait_for_event.h new file mode 100644 index 000000000..2693a0d8c --- /dev/null +++ b/portable/ThirdParty/GCC/Posix/utils/wait_for_event.h @@ -0,0 +1,18 @@ +#ifndef _WAIT_FOR_EVENT_H_ +#define _WAIT_FOR_EVENT_H_ + +#include +#include + +struct event; + +struct event * event_create(); +void event_delete( struct event * ); +bool event_wait( struct event * ev ); +bool event_wait_timed( struct event * ev, + time_t ms ); +void event_signal( struct event * ev ); + + + +#endif /* ifndef _WAIT_FOR_EVENT_H_ */ diff --git a/tasks.c b/tasks.c index 5c0d9929c..5dab76df2 100644 --- a/tasks.c +++ b/tasks.c @@ -4887,7 +4887,7 @@ TickType_t uxTaskResetEventItemValue( void ) /* Should not get here if all enums are handled. * Artificially force an assert by testing a value the * compiler can't assume is const. */ - configASSERT( pxTCB->ulNotifiedValue[ uxIndexToNotify ] == ~0UL ); + configASSERT( xTickCount == ( TickType_t ) 0 ); break; } @@ -5030,7 +5030,7 @@ TickType_t uxTaskResetEventItemValue( void ) /* Should not get here if all enums are handled. * Artificially force an assert by testing a value the * compiler can't assume is const. */ - configASSERT( pxTCB->ulNotifiedValue[ uxIndexToNotify ] == ~0UL ); + configASSERT( xTickCount == ( TickType_t ) 0 ); break; }