diff --git a/cores/arduino/mik32/shared/runtime/crt0.S b/cores/arduino/mik32/shared/runtime/crt0.S index e4185cd..3730d85 100644 --- a/cores/arduino/mik32/shared/runtime/crt0.S +++ b/cores/arduino/mik32/shared/runtime/crt0.S @@ -114,7 +114,9 @@ SystemInit: // default mtvec value (set in scr1_arch_description.svh) //.org 0xC0 trap_entry: - j raw_trap_handler + // j raw_trap_handler + la t0, freertos_risc_v_trap_handler + jalr t0 raw_trap_handler: // Save registers diff --git a/libraries/FreeRTOS/examples/AnalogRead_DigitalRead/AnalogRead_DigitalRead.ino b/libraries/FreeRTOS/examples/AnalogRead_DigitalRead/AnalogRead_DigitalRead.ino index 48821ef..c7888dd 100644 --- a/libraries/FreeRTOS/examples/AnalogRead_DigitalRead/AnalogRead_DigitalRead.ino +++ b/libraries/FreeRTOS/examples/AnalogRead_DigitalRead/AnalogRead_DigitalRead.ino @@ -14,6 +14,7 @@ void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); + Serial.println("Hello"); while (!Serial) { ; // wait for serial port to connect. Needed for native USB, on LEONARDO, MICRO, YUN, and other 32u4 based boards. @@ -52,6 +53,7 @@ void setup() { void loop() { // Empty. Things are done in Tasks. + Serial.println("ping"); } /*--------------------------------------------------*/ diff --git a/libraries/FreeRTOS/src/port.c b/libraries/FreeRTOS/src/port.c new file mode 100644 index 0000000..621aca8 --- /dev/null +++ b/libraries/FreeRTOS/src/port.c @@ -0,0 +1,208 @@ +/* + * FreeRTOS Kernel V11.1.0 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ + +/*----------------------------------------------------------- +* Implementation of functions defined in portable.h for the RISC-V port. +*----------------------------------------------------------*/ + +/* Scheduler includes. */ +#include "Arduino_FreeRTOS.h" +#include "task.h" +#include "portmacro.h" + +/* Standard includes. */ +#include "string.h" + +#ifdef configCLINT_BASE_ADDRESS + #warning "The configCLINT_BASE_ADDRESS constant has been deprecated. configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS are currently being derived from the (possibly 0) configCLINT_BASE_ADDRESS setting. Please update to define configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS directly in place of configCLINT_BASE_ADDRESS. See www.FreeRTOS.org/Using-FreeRTOS-on-RISC-V.html" +#endif + +#ifndef configMTIME_BASE_ADDRESS + #warning "configMTIME_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a memory-mapped mtime register then set configMTIME_BASE_ADDRESS to the mapped address. Otherwise set configMTIME_BASE_ADDRESS to 0. See www.FreeRTOS.org/Using-FreeRTOS-on-RISC-V.html" +#endif + +#ifndef configMTIMECMP_BASE_ADDRESS + #warning "configMTIMECMP_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a memory-mapped mtimecmp register then set configMTIMECMP_BASE_ADDRESS to the mapped address. Otherwise set configMTIMECMP_BASE_ADDRESS to 0. See www.FreeRTOS.org/Using-FreeRTOS-on-RISC-V.html" +#endif + +/* Let the user override the pre-loading of the initial RA. */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS 0 +#endif + +/* The stack used by interrupt service routines. Set configISR_STACK_SIZE_WORDS + * to use a statically allocated array as the interrupt stack. Alternative leave + * configISR_STACK_SIZE_WORDS undefined and update the linker script so that a + * linker variable names __freertos_irq_stack_top has the same value as the top + * of the stack used by main. Using the linker script method will repurpose the + * stack that was used by main before the scheduler was started for use as the + * interrupt stack after the scheduler has started. */ +#ifdef configISR_STACK_SIZE_WORDS +static __attribute__( ( aligned( 16 ) ) ) StackType_t xISRStack[ configISR_STACK_SIZE_WORDS ] = { 0 }; +const StackType_t xISRStackTop = ( StackType_t ) &( xISRStack[ configISR_STACK_SIZE_WORDS & ~portBYTE_ALIGNMENT_MASK ] ); + +/* Don't use 0xa5 as the stack fill bytes as that is used by the kernel for + * the task stacks, and so will legitimately appear in many positions within + * the ISR stack. */ + #define portISR_STACK_FILL_BYTE 0xee +#else + extern const uint32_t __freertos_irq_stack_top[]; + const StackType_t xISRStackTop = ( StackType_t ) __freertos_irq_stack_top; +#endif + +/* + * Setup the timer to generate the tick interrupts. The implementation in this + * file is weak to allow application writers to change the timer used to + * generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ) __attribute__( ( weak ) ); + +/*-----------------------------------------------------------*/ + +/* Used to program the machine timer compare register. */ +uint64_t ullNextTime = 0ULL; +const uint64_t * pullNextTime = &ullNextTime; +const size_t uxTimerIncrementsForOneTick = ( size_t ) ( ( configCPU_CLOCK_HZ ) / ( configTICK_RATE_HZ ) ); /* Assumes increment won't go over 32-bits. */ +const size_t ullMachineTimerCompareRegisterBase = configMTIMECMP_BASE_ADDRESS; +volatile uint64_t * pullMachineTimerCompareRegister = NULL; + +/* Holds the critical nesting value - deliberately non-zero at start up to + * ensure interrupts are not accidentally enabled before the scheduler starts. */ +size_t xCriticalNesting = ( size_t ) 0xaaaaaaaa; +size_t * pxCriticalNesting = &xCriticalNesting; + +/* Used to catch tasks that attempt to return from their implementing function. */ +size_t xTaskReturnAddress = ( size_t ) portTASK_RETURN_ADDRESS; + +/* Set configCHECK_FOR_STACK_OVERFLOW to 3 to add ISR stack checking to task + * stack checking. A problem in the ISR stack will trigger an assert, not call + * the stack overflow hook function (because the stack overflow hook is specific + * to a task stack, not the ISR stack). */ +#if defined( configISR_STACK_SIZE_WORDS ) && ( configCHECK_FOR_STACK_OVERFLOW > 2 ) + #warning "This path not tested, or even compiled yet." + + static const uint8_t ucExpectedStackBytes[] = + { + portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \ + portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \ + portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \ + portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \ + portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE + }; \ + + #define portCHECK_ISR_STACK() configASSERT( ( memcmp( ( void * ) xISRStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) == 0 ) ) +#else /* if defined( configISR_STACK_SIZE_WORDS ) && ( configCHECK_FOR_STACK_OVERFLOW > 2 ) */ + /* Define the function away. */ + #define portCHECK_ISR_STACK() +#endif /* configCHECK_FOR_STACK_OVERFLOW > 2 */ + +/*-----------------------------------------------------------*/ + +#if ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) + + void vPortSetupTimerInterrupt( void ) + { + uint32_t ulCurrentTimeHigh, ulCurrentTimeLow; + volatile uint32_t * const pulTimeHigh = ( volatile uint32_t * const ) ( ( configMTIME_BASE_ADDRESS ) + 4UL ); /* 8-byte type so high 32-bit word is 4 bytes up. */ + volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configMTIME_BASE_ADDRESS ); + volatile uint32_t ulHartId; + + __asm volatile ( "csrr %0, mhartid" : "=r" ( ulHartId ) ); + + pullMachineTimerCompareRegister = ( volatile uint64_t * ) ( ullMachineTimerCompareRegisterBase + ( ulHartId * sizeof( uint64_t ) ) ); + + do + { + ulCurrentTimeHigh = *pulTimeHigh; + ulCurrentTimeLow = *pulTimeLow; + } while( ulCurrentTimeHigh != *pulTimeHigh ); + + ullNextTime = ( uint64_t ) ulCurrentTimeHigh; + ullNextTime <<= 32ULL; /* High 4-byte word is 32-bits up. */ + ullNextTime |= ( uint64_t ) ulCurrentTimeLow; + ullNextTime += ( uint64_t ) uxTimerIncrementsForOneTick; + *pullMachineTimerCompareRegister = ullNextTime; + + /* Prepare the time to use after the next tick interrupt. */ + ullNextTime += ( uint64_t ) uxTimerIncrementsForOneTick; + } + +#endif /* ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIME_BASE_ADDRESS != 0 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t xPortStartScheduler( void ) +{ + extern void xPortStartFirstTask( void ); + + #if ( configASSERT_DEFINED == 1 ) + { + /* Check alignment of the interrupt stack - which is the same as the + * stack that was being used by main() prior to the scheduler being + * started. */ + configASSERT( ( xISRStackTop & portBYTE_ALIGNMENT_MASK ) == 0 ); + + #ifdef configISR_STACK_SIZE_WORDS + { + memset( ( void * ) xISRStack, portISR_STACK_FILL_BYTE, sizeof( xISRStack ) ); + } + #endif /* configISR_STACK_SIZE_WORDS */ + } + #endif /* configASSERT_DEFINED */ + + /* If there is a CLINT then it is ok to use the default implementation + * in this file, otherwise vPortSetupTimerInterrupt() must be implemented to + * configure whichever clock is to be used to generate the tick interrupt. */ + vPortSetupTimerInterrupt(); + + #if ( ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) ) + { + /* Enable mtime and external interrupts. 1<<7 for timer interrupt, + * 1<<11 for external interrupt. _RB_ What happens here when mtime is + * not present as with pulpino? */ + __asm volatile ( "csrs mie, %0" ::"r" ( 0x880 ) ); + } + #endif /* ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) */ + + xPortStartFirstTask(); + + /* Should not get here as after calling xPortStartFirstTask() only tasks + * should be executing. */ + return pdFAIL; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented. */ + for( ; ; ) + { + } +} +/*-----------------------------------------------------------*/ diff --git a/libraries/FreeRTOS/src/portContext.h b/libraries/FreeRTOS/src/portContext.h new file mode 100644 index 0000000..5f1498c --- /dev/null +++ b/libraries/FreeRTOS/src/portContext.h @@ -0,0 +1,192 @@ +/* + * FreeRTOS Kernel V11.1.0 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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 + * + */ + +#ifndef PORTCONTEXT_H +#define PORTCONTEXT_H + +#if __riscv_xlen == 64 + #define portWORD_SIZE 8 + #define store_x sd + #define load_x ld +#elif __riscv_xlen == 32 + #define store_x sw + #define load_x lw + #define portWORD_SIZE 4 +#else + #error Assembler did not define __riscv_xlen +#endif + +#include "freertos_risc_v_chip_specific_extensions.h" + +/* Only the standard core registers are stored by default. Any additional + * registers must be saved by the portasmSAVE_ADDITIONAL_REGISTERS and + * portasmRESTORE_ADDITIONAL_REGISTERS macros - which can be defined in a chip + * specific version of freertos_risc_v_chip_specific_extensions.h. See the + * notes at the top of portASM.S file. */ +#ifdef __riscv_32e + #define portCONTEXT_SIZE ( 15 * portWORD_SIZE ) + #define portCRITICAL_NESTING_OFFSET 13 + #define portMSTATUS_OFFSET 14 +#else + #define portCONTEXT_SIZE ( 31 * portWORD_SIZE ) + #define portCRITICAL_NESTING_OFFSET 29 + #define portMSTATUS_OFFSET 30 +#endif + +/*-----------------------------------------------------------*/ + +.extern pxCurrentTCB + .extern xISRStackTop + .extern xCriticalNesting + .extern pxCriticalNesting +/*-----------------------------------------------------------*/ + + .macro portcontextSAVE_CONTEXT_INTERNAL +addi sp, sp, -portCONTEXT_SIZE +store_x x1, 1 * portWORD_SIZE( sp ) +store_x x5, 2 * portWORD_SIZE( sp ) +store_x x6, 3 * portWORD_SIZE( sp ) +store_x x7, 4 * portWORD_SIZE( sp ) +store_x x8, 5 * portWORD_SIZE( sp ) +store_x x9, 6 * portWORD_SIZE( sp ) +store_x x10, 7 * portWORD_SIZE( sp ) +store_x x11, 8 * portWORD_SIZE( sp ) +store_x x12, 9 * portWORD_SIZE( sp ) +store_x x13, 10 * portWORD_SIZE( sp ) +store_x x14, 11 * portWORD_SIZE( sp ) +store_x x15, 12 * portWORD_SIZE( sp ) +#ifndef __riscv_32e + store_x x16, 13 * portWORD_SIZE( sp ) + store_x x17, 14 * portWORD_SIZE( sp ) + store_x x18, 15 * portWORD_SIZE( sp ) + store_x x19, 16 * portWORD_SIZE( sp ) + store_x x20, 17 * portWORD_SIZE( sp ) + store_x x21, 18 * portWORD_SIZE( sp ) + store_x x22, 19 * portWORD_SIZE( sp ) + store_x x23, 20 * portWORD_SIZE( sp ) + store_x x24, 21 * portWORD_SIZE( sp ) + store_x x25, 22 * portWORD_SIZE( sp ) + store_x x26, 23 * portWORD_SIZE( sp ) + store_x x27, 24 * portWORD_SIZE( sp ) + store_x x28, 25 * portWORD_SIZE( sp ) + store_x x29, 26 * portWORD_SIZE( sp ) + store_x x30, 27 * portWORD_SIZE( sp ) + store_x x31, 28 * portWORD_SIZE( sp ) +#endif /* ifndef __riscv_32e */ + +load_x t0, xCriticalNesting /* Load the value of xCriticalNesting into t0. */ +store_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Store the critical nesting value to the stack. */ + + +csrr t0, mstatus /* Required for MPIE bit. */ +store_x t0, portMSTATUS_OFFSET * portWORD_SIZE( sp ) + + +portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */ + +load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */ +store_x sp, 0 ( t0 ) /* Write sp to first TCB member. */ + + .endm +/*-----------------------------------------------------------*/ + + .macro portcontextSAVE_EXCEPTION_CONTEXT +portcontextSAVE_CONTEXT_INTERNAL +csrr a0, mcause +csrr a1, mepc +addi a1, a1, 4 /* Synchronous so update exception return address to the instruction after the instruction that generated the exception. */ +store_x a1, 0 ( sp ) /* Save updated exception return address. */ +load_x sp, xISRStackTop /* Switch to ISR stack. */ + .endm +/*-----------------------------------------------------------*/ + + .macro portcontextSAVE_INTERRUPT_CONTEXT +portcontextSAVE_CONTEXT_INTERNAL +csrr a0, mcause +csrr a1, mepc +store_x a1, 0 ( sp ) /* Asynchronous interrupt so save unmodified exception return address. */ +load_x sp, xISRStackTop /* Switch to ISR stack. */ + .endm +/*-----------------------------------------------------------*/ + + .macro portcontextRESTORE_CONTEXT +load_x t1, pxCurrentTCB /* Load pxCurrentTCB. */ +load_x sp, 0 ( t1 ) /* Read sp from first TCB member. */ + +/* Load mepc with the address of the instruction in the task to run next. */ +load_x t0, 0 ( sp ) +csrw mepc, t0 + +/* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */ +portasmRESTORE_ADDITIONAL_REGISTERS + +/* Load mstatus with the interrupt enable bits used by the task. */ +load_x t0, portMSTATUS_OFFSET * portWORD_SIZE( sp ) +csrw mstatus, t0 /* Required for MPIE bit. */ + +load_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Obtain xCriticalNesting value for this task from task's stack. */ +load_x t1, pxCriticalNesting /* Load the address of xCriticalNesting into t1. */ +store_x t0, 0 ( t1 ) /* Restore the critical nesting value for this task. */ + +load_x x1, 1 * portWORD_SIZE( sp ) +load_x x5, 2 * portWORD_SIZE( sp ) +load_x x6, 3 * portWORD_SIZE( sp ) +load_x x7, 4 * portWORD_SIZE( sp ) +load_x x8, 5 * portWORD_SIZE( sp ) +load_x x9, 6 * portWORD_SIZE( sp ) +load_x x10, 7 * portWORD_SIZE( sp ) +load_x x11, 8 * portWORD_SIZE( sp ) +load_x x12, 9 * portWORD_SIZE( sp ) +load_x x13, 10 * portWORD_SIZE( sp ) +load_x x14, 11 * portWORD_SIZE( sp ) +load_x x15, 12 * portWORD_SIZE( sp ) +#ifndef __riscv_32e + load_x x16, 13 * portWORD_SIZE( sp ) + load_x x17, 14 * portWORD_SIZE( sp ) + load_x x18, 15 * portWORD_SIZE( sp ) + load_x x19, 16 * portWORD_SIZE( sp ) + load_x x20, 17 * portWORD_SIZE( sp ) + load_x x21, 18 * portWORD_SIZE( sp ) + load_x x22, 19 * portWORD_SIZE( sp ) + load_x x23, 20 * portWORD_SIZE( sp ) + load_x x24, 21 * portWORD_SIZE( sp ) + load_x x25, 22 * portWORD_SIZE( sp ) + load_x x26, 23 * portWORD_SIZE( sp ) + load_x x27, 24 * portWORD_SIZE( sp ) + load_x x28, 25 * portWORD_SIZE( sp ) + load_x x29, 26 * portWORD_SIZE( sp ) + load_x x30, 27 * portWORD_SIZE( sp ) + load_x x31, 28 * portWORD_SIZE( sp ) +#endif /* ifndef __riscv_32e */ +addi sp, sp, portCONTEXT_SIZE + +mret + .endm +/*-----------------------------------------------------------*/ + +#endif /* PORTCONTEXT_H */ diff --git a/libraries/FreeRTOS/src/variantHooks.cpp b/libraries/FreeRTOS/src/variantHooks.cpp new file mode 100644 index 0000000..f6cd254 --- /dev/null +++ b/libraries/FreeRTOS/src/variantHooks.cpp @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2024 Phillip Stevens 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 is NOT part of the FreeRTOS distribution. + * + */ +#include + + +#include + +/* FreeRTOS includes. */ +#include "Arduino_FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "mik32_hal_scr1_timer.h" + +extern void setup(void); +extern void loop(void); + +/*-----------------------------------------------------------*/ + +void initVariant(void) +{ + setup(); // the normal Arduino setup() function is run here. + post_init(); + vTaskStartScheduler(); // initialise and run the freeRTOS scheduler. Execution should never return here. +} + +/* + * Setup the timer to generate the tick interrupts. + * The basic settings have been applied at startup in function SystemInit(), + * now all that remains is to configure the machine timer comparison register + * and enable this interrupt. + */ +void vPortSetupTimerInterrupt(void) +{ + + SCR1_TIMER->MTIMEH; SCR1_TIMER->MTIME; + SCR1_TIMER->MTIMECMP; SCR1_TIMER->MTIMECMPH; +} + +/*-----------------------------------------------------------*/ +#if ( configUSE_IDLE_HOOK == 1 ) +/* + * Call the user defined loop() function from within the idle task. + * This allows the application designer to add background functionality + * without the overhead of a separate task. + * + * NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, CALL A FUNCTION THAT MIGHT BLOCK. + * + */ +void vApplicationIdleHook( void ) __attribute__ ((weak)); + +void vApplicationIdleHook( void ) +{ + loop(); // the normal Arduino loop() function is run here. +} + +#else + void loop() {} //Empty loop function +#endif /* configUSE_IDLE_HOOK == 1 */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MALLOC_FAILED_HOOK == 1 || configCHECK_FOR_STACK_OVERFLOW >= 1 || configDEFAULT_ASSERT == 1 ) + +/** + * Private function to enable board led to use it in application hooks + */ +void prvSetMainLedOn( void ) +{ +#if defined (LED_BUILTIN) + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, HIGH); +#endif +} + +/** + * Private function to blink board led to use it in application hooks + */ +void prvBlinkMainLed( void ) +{ +#if defined (LED_BUILTIN) + digitalToggle(LED_BUILTIN); +#endif + +} + +#endif + +#if ( configUSE_MALLOC_FAILED_HOOK == 1 ) +/*---------------------------------------------------------------------------*\ +Usage: + called by task system when a malloc failure is noticed +Description: + Malloc failure handler -- Shut down all interrupts, send serious complaint + to command port. FAST Blink on main LED. +Arguments: + pxTask - pointer to task handle + pcTaskName - pointer to task name +Results: + +Notes: + This routine will never return. + This routine is referenced in the task.c file of FreeRTOS as an extern. +\*---------------------------------------------------------------------------*/ +void vApplicationMallocFailedHook( void ) __attribute__ ((weak)); + +void vApplicationMallocFailedHook( void ) +{ + prvSetMainLedOn(); // Main LED on. + + for(;;) + { + delay(50); + prvBlinkMainLed(); // Main LED fast blink. + } +} + +#endif /* configUSE_MALLOC_FAILED_HOOK == 1 */ +/*-----------------------------------------------------------*/ + + +#if ( configCHECK_FOR_STACK_OVERFLOW >= 1 ) + +void vApplicationStackOverflowHook( TaskHandle_t xTask, + char * pcTaskName ) __attribute__ ((weak)); + +void vApplicationStackOverflowHook( TaskHandle_t xTask __attribute__ ((unused)), + char * pcTaskName __attribute__ ((unused)) ) +{ + + prvSetMainLedOn(); // Main LED on. + + for(;;) + { + // _delay_ms(2000); + prvBlinkMainLed(); // Main LED slow blink. + } +} + +#endif /* configCHECK_FOR_STACK_OVERFLOW >= 1 */ +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION >= 1 ) + +void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, + StackType_t ** ppxIdleTaskStackBuffer, + configSTACK_DEPTH_TYPE * puxIdleTaskStackSize ) __attribute__ ((weak)); + +void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, + StackType_t ** ppxIdleTaskStackBuffer, + configSTACK_DEPTH_TYPE * puxIdleTaskStackSize ) +{ + static StaticTask_t xIdleTaskTCB; + static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; + + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + *puxIdleTaskStackSize = configMINIMAL_STACK_SIZE; +} + +#if ( configUSE_TIMERS >= 1 ) + +void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, + StackType_t ** ppxTimerTaskStackBuffer, + configSTACK_DEPTH_TYPE * puxTimerTaskStackSize ) __attribute__ ((weak)); + +void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, + StackType_t ** ppxTimerTaskStackBuffer, + configSTACK_DEPTH_TYPE * puxTimerTaskStackSize ) +{ + static StaticTask_t xTimerTaskTCB; + static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; + + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + *puxTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; +} + +#endif /* configUSE_TIMERS >= 1 */ + +#endif /* configSUPPORT_STATIC_ALLOCATION >= 1 */ + +/** + * configASSERT default implementation + */ +#if configDEFAULT_ASSERT == 1 + +void vApplicationAssertHook() { + + taskDISABLE_INTERRUPTS(); // Disable task interrupts + + prvSetMainLedOn(); // Main LED on. + for(;;) + { + // todo тут тоже заменить + delay(100); + prvBlinkMainLed(); // Led off. + + delay(2000); + prvBlinkMainLed(); // Led on. + + delay(100); + prvBlinkMainLed(); // Led off + + delay(100); + prvBlinkMainLed(); // Led on. + } +} +#endif diff --git a/platform.txt b/platform.txt index 675e888..2392730 100644 --- a/platform.txt +++ b/platform.txt @@ -33,7 +33,7 @@ compiler.optimization_flags.release=-Os compiler.optimization_flags.debug=-Og -g3 compiler.extra_flags = -march=rv32imc_zicsr_zifencei -mabi=ilp32 -mcmodel=medlow -Wall -fsigned-char -ffunction-sections -compiler.S.flags = {compiler.extra_flags} -x assembler-with-cpp {compiler.define} {compiler.optimization_flags} {compiler.warning_flags} {compiler.MIK32_Amur.extra_include} +compiler.S.flags = {compiler.extra_flags} -x assembler-with-cpp {compiler.define} -I"{runtime.platform.path}/libraries/FreeRTOS/src" {compiler.optimization_flags} {compiler.warning_flags} {compiler.MIK32_Amur.extra_include} compiler.c.flags = -c -std=gnu11 {compiler.extra_flags} {compiler.define} {compiler.warning_flags} {compiler.optimization_flags} {compiler.MIK32_Amur.extra_include} compiler.cpp.flags = -c -std=gnu++17 -fabi-version=0 -fno-exceptions -fno-rtti -fno-use-cxa-atexit -fno-threadsafe-statics {compiler.extra_flags} {compiler.define} {compiler.warning_flags} {compiler.optimization_flags} {compiler.MIK32_Amur.extra_include} compiler.c.elf.flags = -march=rv32imc_zicsr_zifencei -mabi=ilp32 -mcmodel=medlow -nostartfiles -Xlinker