From 4539e1c57484720bdb601057ee85f0f40059f13f Mon Sep 17 00:00:00 2001 From: Felipe Torrezan Date: Thu, 24 Feb 2022 18:04:46 +0100 Subject: [PATCH] Migrated RL78/IAR port to EWRL78v3+ (#461) Co-authored-by: Cobus van Eeden <35851496+cobusve@users.noreply.github.com> --- portable/IAR/RL78/ISR_Support.h | 84 ----------- portable/IAR/RL78/port.c | 249 ++++++++++++-------------------- portable/IAR/RL78/portasm.s | 84 +++++++++++ portable/IAR/RL78/portasm.s87 | 84 ----------- portable/IAR/RL78/portmacro.h | 169 ++++++++++++++++------ 5 files changed, 299 insertions(+), 371 deletions(-) delete mode 100644 portable/IAR/RL78/ISR_Support.h create mode 100644 portable/IAR/RL78/portasm.s delete mode 100644 portable/IAR/RL78/portasm.s87 diff --git a/portable/IAR/RL78/ISR_Support.h b/portable/IAR/RL78/ISR_Support.h deleted file mode 100644 index 7ceed2d59..000000000 --- a/portable/IAR/RL78/ISR_Support.h +++ /dev/null @@ -1,84 +0,0 @@ -;/* -; * FreeRTOS Kernel -; * 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 -; * -; */ - - -#include "FreeRTOSConfig.h" - -; Variables used by scheduler -;------------------------------------------------------------------------------ - EXTERN pxCurrentTCB - EXTERN usCriticalNesting - -;------------------------------------------------------------------------------ -; portSAVE_CONTEXT MACRO -; Saves the context of the general purpose registers, CS and ES (only in far -; memory mode) registers the usCriticalNesting Value and the Stack Pointer -; of the active Task onto the task stack -;------------------------------------------------------------------------------ -portSAVE_CONTEXT MACRO - - PUSH AX ; Save AX Register to stack. - PUSH HL - MOV A, CS ; Save CS register. - XCH A, X - MOV A, ES ; Save ES register. - PUSH AX - PUSH DE ; Save the remaining general purpose registers. - PUSH BC - MOVW AX, usCriticalNesting ; Save the usCriticalNesting value. - PUSH AX - MOVW AX, pxCurrentTCB ; Save the Stack pointer. - MOVW HL, AX - MOVW AX, SP - MOVW [HL], AX - ENDM -;------------------------------------------------------------------------------ - -;------------------------------------------------------------------------------ -; portRESTORE_CONTEXT MACRO -; Restores the task Stack Pointer then use this to restore usCriticalNesting, -; general purpose registers and the CS and ES (only in far memory mode) -; of the selected task from the task stack -;------------------------------------------------------------------------------ -portRESTORE_CONTEXT MACRO - MOVW AX, pxCurrentTCB ; Restore the Stack pointer. - MOVW HL, AX - MOVW AX, [HL] - MOVW SP, AX - POP AX ; Restore usCriticalNesting value. - MOVW usCriticalNesting, AX - POP BC ; Restore the necessary general purpose registers. - POP DE - POP AX ; Restore the ES register. - MOV ES, A - XCH A, X ; Restore the CS register. - MOV CS, A - POP HL ; Restore general purpose register HL. - POP AX ; Restore AX. - ENDM -;------------------------------------------------------------------------------ diff --git a/portable/IAR/RL78/port.c b/portable/IAR/RL78/port.c index 8e6e7e430..7cfc02b1d 100644 --- a/portable/IAR/RL78/port.c +++ b/portable/IAR/RL78/port.c @@ -45,7 +45,7 @@ interrupts don't accidentally become enabled before the scheduler is started. */ * |--------------------- Zero Flag set * ---------------------- Global Interrupt Flag set (enabled) */ -#define portPSW ( 0xc6UL ) +#define portPSW ( 0xc6UL ) /* The address of the pxCurrentTCB variable, but don't know or need to know its type. */ @@ -65,21 +65,13 @@ volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING; /*-----------------------------------------------------------*/ /* - * Sets up the periodic ISR used for the RTOS tick using the interval timer. - * The application writer can define configSETUP_TICK_INTERRUPT() (in - * FreeRTOSConfig.h) such that their own tick interrupt configuration is used - * in place of prvSetupTimerInterrupt(). + * Sets up the periodic ISR used for the RTOS tick. */ -static void prvSetupTimerInterrupt( void ); -#ifndef configSETUP_TICK_INTERRUPT - /* The user has not provided their own tick interrupt configuration so use - the definition in this file (which uses the interval timer). */ - #define configSETUP_TICK_INTERRUPT() prvSetupTimerInterrupt() -#endif /* configSETUP_TICK_INTERRUPT */ +extern void vApplicationSetupTimerInterrupt( void ); /* - * Defined in portasm.s87, this function starts the scheduler by loading the - * context of the first task to run. + * Starts the scheduler by loading the context of the first Task to run. + * (implemented in portasm.s). */ extern void vPortStartFirstTask( void ); @@ -100,182 +92,119 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px { uint32_t *pulLocal; - /* With large code and large data sizeof( StackType_t ) == 2, and - sizeof( StackType_t * ) == 4. With small code and small data - sizeof( StackType_t ) == 2 and sizeof( StackType_t * ) == 2. */ + /* With large code and large data sizeof( StackType_t ) == 2, and + sizeof( StackType_t * ) == 4. With small code and small data + sizeof( StackType_t ) == 2 and sizeof( StackType_t * ) == 2. */ - #if __DATA_MODEL__ == __DATA_MODEL_FAR__ - { - /* Parameters are passed in on the stack, and written using a 32-bit value - hence a space is left for the second two bytes. */ - pxTopOfStack--; + #if __DATA_MODEL__ == __DATA_MODEL_FAR__ + { + /* Far pointer parameters are passed using the A:DE registers (24-bit). + Although they are stored in memory as a 32-bit value. Hence decrement + the stack pointer, so 2 bytes are left for the contents of A, before + storing the pvParameters value. */ + pxTopOfStack--; + pulLocal = ( uint32_t * ) pxTopOfStack; + *pulLocal = ( uint32_t ) pvParameters; + pxTopOfStack--; - /* Write in the parameter value. */ - pulLocal = ( uint32_t * ) pxTopOfStack; - *pulLocal = ( uint32_t ) pvParameters; - pxTopOfStack--; + /* The return address is a 32-bit value. So decrement the stack pointer + in order to make extra room needed to store the correct value. See the + comments above the prvTaskExitError() prototype at the top of this file. */ + pxTopOfStack--; + pulLocal = ( uint32_t * ) pxTopOfStack; + *pulLocal = ( uint32_t ) prvTaskExitError; + pxTopOfStack--; - /* The return address, leaving space for the first two bytes of the - 32-bit value. See the comments above the prvTaskExitError() prototype - at the top of this file. */ - pxTopOfStack--; - pulLocal = ( uint32_t * ) pxTopOfStack; - *pulLocal = ( uint32_t ) prvTaskExitError; - pxTopOfStack--; + /* The task function start address combined with the PSW is also stored + as a 32-bit value. So leave a space for the second two bytes. */ + pxTopOfStack--; + pulLocal = ( uint32_t * ) pxTopOfStack; + *pulLocal = ( ( ( uint32_t ) pxCode ) | ( portPSW << 24UL ) ); + pxTopOfStack--; - /* The start address / PSW value is also written in as a 32-bit value, - so leave a space for the second two bytes. */ - pxTopOfStack--; + /* An initial value for the AX register. */ + *pxTopOfStack = ( StackType_t ) 0x1111; + pxTopOfStack--; + } + #else + { + /* The return address, leaving space for the first two bytes of the + 32-bit value. See the comments above the prvTaskExitError() prototype + at the top of this file. */ + pxTopOfStack--; + pulLocal = ( uint32_t * ) pxTopOfStack; + *pulLocal = ( uint32_t ) prvTaskExitError; + pxTopOfStack--; - /* Task function start address combined with the PSW. */ - pulLocal = ( uint32_t * ) pxTopOfStack; - *pulLocal = ( ( ( uint32_t ) pxCode ) | ( portPSW << 24UL ) ); - pxTopOfStack--; + /* Task function. Again as it is written as a 32-bit value a space is + left on the stack for the second two bytes. */ + pxTopOfStack--; - /* An initial value for the AX register. */ - *pxTopOfStack = ( StackType_t ) 0x1111; - pxTopOfStack--; - } - #else - { - /* The return address, leaving space for the first two bytes of the - 32-bit value. See the comments above the prvTaskExitError() prototype - at the top of this file. */ - pxTopOfStack--; - pulLocal = ( uint32_t * ) pxTopOfStack; - *pulLocal = ( uint32_t ) prvTaskExitError; - pxTopOfStack--; + /* Task function start address combined with the PSW. */ + pulLocal = ( uint32_t * ) pxTopOfStack; + *pulLocal = ( ( ( uint32_t ) pxCode ) | ( portPSW << 24UL ) ); + pxTopOfStack--; - /* Task function. Again as it is written as a 32-bit value a space is - left on the stack for the second two bytes. */ - pxTopOfStack--; + /* The parameter is passed in AX. */ + *pxTopOfStack = ( StackType_t ) pvParameters; + pxTopOfStack--; + } + #endif - /* Task function start address combined with the PSW. */ - pulLocal = ( uint32_t * ) pxTopOfStack; - *pulLocal = ( ( ( uint32_t ) pxCode ) | ( portPSW << 24UL ) ); - pxTopOfStack--; + /* An initial value for the HL register. */ + *pxTopOfStack = ( StackType_t ) 0x2222; + pxTopOfStack--; - /* The parameter is passed in AX. */ - *pxTopOfStack = ( StackType_t ) pvParameters; - pxTopOfStack--; - } - #endif + /* CS and ES registers. */ + *pxTopOfStack = ( StackType_t ) 0x0F00; + pxTopOfStack--; - /* An initial value for the HL register. */ - *pxTopOfStack = ( StackType_t ) 0x2222; - pxTopOfStack--; + /* The remaining general purpose registers DE and BC */ + *pxTopOfStack = ( StackType_t ) 0xDEDE; + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0xBCBC; + pxTopOfStack--; - /* CS and ES registers. */ - *pxTopOfStack = ( StackType_t ) 0x0F00; - pxTopOfStack--; + /* Finally the critical section nesting count is set to zero when the task + first starts. */ + *pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING; - /* The remaining general purpose registers DE and BC */ - *pxTopOfStack = ( StackType_t ) 0xDEDE; - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0xBCBC; - pxTopOfStack--; - - /* Finally the critical section nesting count is set to zero when the task - first starts. */ - *pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING; - - /* Return a pointer to the top of the stack that has been generated so it - can be stored in the task control block for the task. */ - return pxTopOfStack; + /* Return a pointer to the top of the stack that has been generated so + it can be stored in the task control block for the task. */ + return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) { - /* A function that implements a task must not exit or attempt to return to - its caller as there is nothing to return to. If a task wants to exit it - should instead call vTaskDelete( NULL ). + /* A function that implements a task must not exit or attempt to return to + its caller as there is nothing to return to. If a task wants to exit it + should instead call vTaskDelete( NULL ). - Artificially force an assert() to be triggered if configASSERT() is - defined, then stop here so application writers can catch the error. */ - configASSERT( usCriticalNesting == ~0U ); - portDISABLE_INTERRUPTS(); - for( ;; ); + Artificially force an assert() to be triggered if configASSERT() is + defined, then stop here so application writers can catch the error. */ + configASSERT( usCriticalNesting == ~0U ); + portDISABLE_INTERRUPTS(); + for( ;; ); } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) { - /* Setup the hardware to generate the tick. Interrupts are disabled when - this function is called. */ - configSETUP_TICK_INTERRUPT(); + /* Setup the hardware to generate the tick. Interrupts are disabled when + this function is called. */ + vApplicationSetupTimerInterrupt(); - /* Restore the context of the first task that is going to run. */ - vPortStartFirstTask(); + /* Restore the context of the first task that is going to run. */ + vPortStartFirstTask(); - /* Execution should not reach here as the tasks are now running! - prvSetupTimerInterrupt() is called here to prevent the compiler outputting - a warning about a statically declared function not being referenced in the - case that the application writer has provided their own tick interrupt - configuration routine (and defined configSETUP_TICK_INTERRUPT() such that - their own routine will be called in place of prvSetupTimerInterrupt()). */ - prvSetupTimerInterrupt(); - return pdTRUE; + /* Execution should not reach here as the tasks are now running! */ + return pdTRUE; } /*-----------------------------------------------------------*/ void vPortEndScheduler( void ) { - /* It is unlikely that the RL78 port will get stopped. */ + /* It is unlikely that the RL78 port will get stopped. */ } /*-----------------------------------------------------------*/ - -static void prvSetupTimerInterrupt( void ) -{ -const uint16_t usClockHz = 15000UL; /* Internal clock. */ -const uint16_t usCompareMatch = ( usClockHz / configTICK_RATE_HZ ) + 1UL; - - /* Use the internal 15K clock. */ - OSMC = ( uint8_t ) 0x16; - - #ifdef RTCEN - { - /* Supply the interval timer clock. */ - RTCEN = ( uint8_t ) 1U; - - /* Disable INTIT interrupt. */ - ITMK = ( uint8_t ) 1; - - /* Disable ITMC operation. */ - ITMC = ( uint8_t ) 0x0000; - - /* Clear INIT interrupt. */ - ITIF = ( uint8_t ) 0; - - /* Set interval and enable interrupt operation. */ - ITMC = usCompareMatch | 0x8000U; - - /* Enable INTIT interrupt. */ - ITMK = ( uint8_t ) 0; - } - #endif - - #ifdef TMKAEN - { - /* Supply the interval timer clock. */ - TMKAEN = ( uint8_t ) 1U; - - /* Disable INTIT interrupt. */ - TMKAMK = ( uint8_t ) 1; - - /* Disable ITMC operation. */ - ITMC = ( uint8_t ) 0x0000; - - /* Clear INIT interrupt. */ - TMKAIF = ( uint8_t ) 0; - - /* Set interval and enable interrupt operation. */ - ITMC = usCompareMatch | 0x8000U; - - /* Enable INTIT interrupt. */ - TMKAMK = ( uint8_t ) 0; - } - #endif -} -/*-----------------------------------------------------------*/ - diff --git a/portable/IAR/RL78/portasm.s b/portable/IAR/RL78/portasm.s new file mode 100644 index 000000000..f328d1bec --- /dev/null +++ b/portable/IAR/RL78/portasm.s @@ -0,0 +1,84 @@ +;/* +; * FreeRTOS Kernel +; * 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 +; * +; */ + +#include "portmacro.h" + + EXTERN _vTaskSwitchContext + EXTERN _xTaskIncrementTick + + EXTERN _interrupt_vector_table + + PUBLIC _vPortYield + PUBLIC _vPortStartFirstTask + PUBLIC _vPortTickISR + +#if !defined(__IASMRL78__) || (__VER__ < 310) + #error "This port requires the IAR Assembler for RL78 version 3.10 or later." +#endif + +;------------------------------------------------------------------------------- +; FreeRTOS yield handler. This is installed as the BRK software interrupt +; handler. +;------------------------------------------------------------------------------- + SECTION `.text`:CODE:ROOT(1) +_vPortYield: + portSAVE_CONTEXT ; Save the context of the current task. + RCALL (_vTaskSwitchContext) ; Call the scheduler to select the next task. + portRESTORE_CONTEXT ; Restore the context of the next task to run. + RETB +;------------------------------------------------------------------------------- + + +;------------------------------------------------------------------------------- +; Starts the scheduler by restoring the context of the task that will execute +; first. +;------------------------------------------------------------------------------- + SECTION `.text`:CODE:ROOT(1) +_vPortStartFirstTask: + portRESTORE_CONTEXT ; Restore the context of whichever task the ... + RETI ; An interrupt stack frame is used so the + ; task is started using a RETI instruction. +;------------------------------------------------------------------------------- + + +;------------------------------------------------------------------------------- +; FreeRTOS Timer Tick handler. +; This is installed as the interval timer interrupt handler. +;------------------------------------------------------------------------------- + SECTION `.text`:CODE:ROOT(1) +_vPortTickISR: + portSAVE_CONTEXT ; Save the context of the current task. + RCALL (_xTaskIncrementTick) ; Call the timer tick function. + CMPW AX, #0x00 + SKZ + RCALL (_vTaskSwitchContext) ; Call the scheduler to select the next task. + portRESTORE_CONTEXT ; Restore the context of the next task to run. + RETI +;------------------------------------------------------------------------------- + + END diff --git a/portable/IAR/RL78/portasm.s87 b/portable/IAR/RL78/portasm.s87 deleted file mode 100644 index 6d68649e7..000000000 --- a/portable/IAR/RL78/portasm.s87 +++ /dev/null @@ -1,84 +0,0 @@ -;/* -; * FreeRTOS Kernel -; * 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 -; * -; */ - -#include "ISR_Support.h" - -#define CS 0xFFFFC -#define ES 0xFFFFD - - PUBLIC vPortYield - PUBLIC vPortStartFirstTask - PUBLIC vPortTickISR - - EXTERN vTaskSwitchContext - EXTERN xTaskIncrementTick - -; FreeRTOS yield handler. This is installed as the BRK software interrupt -; handler. - RSEG CODE:CODE -vPortYield: - portSAVE_CONTEXT ; Save the context of the current task. - call vTaskSwitchContext ; Call the scheduler to select the next task. - portRESTORE_CONTEXT ; Restore the context of the next task to run. - retb - - -; Starts the scheduler by restoring the context of the task that will execute -; first. - RSEG CODE:CODE -vPortStartFirstTask: - portRESTORE_CONTEXT ; Restore the context of whichever task the ... - reti ; An interrupt stack frame is used so the task - ; is started using a RETI instruction. - -; FreeRTOS tick handler. This is installed as the interval timer interrupt -; handler. - RSEG CODE:CODE -vPortTickISR: - - portSAVE_CONTEXT ; Save the context of the current task. - call xTaskIncrementTick ; Call the timer tick function. - cmpw ax, #0x00 - skz - call vTaskSwitchContext ; Call the scheduler to select the next task. - portRESTORE_CONTEXT ; Restore the context of the next task to run. - reti - - -; Install the interrupt handlers - - COMMON INTVEC:CODE:ROOT(1) - ORG configTICK_VECTOR - DW vPortTickISR - - COMMON INTVEC:CODE:ROOT(1) - ORG 126 - DW vPortYield - - - END diff --git a/portable/IAR/RL78/portmacro.h b/portable/IAR/RL78/portmacro.h index f183352d1..024312543 100644 --- a/portable/IAR/RL78/portmacro.h +++ b/portable/IAR/RL78/portmacro.h @@ -29,6 +29,8 @@ #ifndef PORTMACRO_H #define PORTMACRO_H +#ifdef __IAR_SYSTEMS_ICC__ + #ifdef __cplusplus extern "C" { #endif @@ -44,11 +46,11 @@ extern "C" { */ #if __DATA_MODEL__ == __DATA_MODEL_FAR__ && __CODE_MODEL__ == __CODE_MODEL_NEAR__ - #warning This port has not been tested with your selected memory model combination. If a far data model is required it is recommended to also use a far code model. + #warning This port has not been tested with your selected memory model combination. If a far data model is required it is recommended to also use a far code model. #endif #if __DATA_MODEL__ == __DATA_MODEL_NEAR__ && __CODE_MODEL__ == __CODE_MODEL_FAR__ - #warning This port has not been tested with your selected memory model combination. If a far code model is required it is recommended to also use a far data model. + #warning This port has not been tested with your selected memory model combination. If a far code model is required it is recommended to also use a far data model. #endif /* Type definitions. */ @@ -67,70 +69,70 @@ typedef unsigned short UBaseType_t; #if __DATA_MODEL__ == __DATA_MODEL_FAR__ - #define portPOINTER_SIZE_TYPE uint32_t + #define portPOINTER_SIZE_TYPE uint32_t #else - #define portPOINTER_SIZE_TYPE uint16_t + #define portPOINTER_SIZE_TYPE uint16_t #endif #if ( configUSE_16_BIT_TICKS == 1 ) - typedef unsigned int TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff + typedef unsigned int TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL #endif /*-----------------------------------------------------------*/ /* Interrupt control macros. */ -#define portDISABLE_INTERRUPTS() __asm ( "DI" ) -#define portENABLE_INTERRUPTS() __asm ( "EI" ) +#define portDISABLE_INTERRUPTS() __asm ( "DI" ) +#define portENABLE_INTERRUPTS() __asm ( "EI" ) /*-----------------------------------------------------------*/ /* Critical section control macros. */ -#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 ) +#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 ) -#define portENTER_CRITICAL() \ -{ \ -extern volatile uint16_t usCriticalNesting; \ - \ - portDISABLE_INTERRUPTS(); \ - \ - /* Now interrupts are disabled ulCriticalNesting can be accessed */ \ - /* directly. Increment ulCriticalNesting to keep a count of how many */ \ - /* times portENTER_CRITICAL() has been called. */ \ - usCriticalNesting++; \ +#define portENTER_CRITICAL() \ +{ \ +extern volatile uint16_t usCriticalNesting; \ + \ + portDISABLE_INTERRUPTS(); \ + \ + /* Now interrupts are disabled ulCriticalNesting can be accessed */ \ + /* directly. Increment ulCriticalNesting to keep a count of how many */ \ + /* times portENTER_CRITICAL() has been called. */ \ + usCriticalNesting++; \ } -#define portEXIT_CRITICAL() \ -{ \ -extern volatile uint16_t usCriticalNesting; \ - \ - if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \ - { \ - /* Decrement the nesting count as we are leaving a critical section. */ \ - usCriticalNesting--; \ - \ - /* If the nesting level has reached zero then interrupts should be */ \ - /* re-enabled. */ \ - if( usCriticalNesting == portNO_CRITICAL_SECTION_NESTING ) \ - { \ - portENABLE_INTERRUPTS(); \ - } \ - } \ +#define portEXIT_CRITICAL() \ +{ \ +extern volatile uint16_t usCriticalNesting; \ + \ + if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \ + { \ + /* Decrement the nesting count when leaving a critical section. */ \ + usCriticalNesting--; \ + \ + /* If the nesting level has reached zero then interrupts should be */ \ + /* re-enabled. */ \ + if( usCriticalNesting == portNO_CRITICAL_SECTION_NESTING ) \ + { \ + portENABLE_INTERRUPTS(); \ + } \ + } \ } /*-----------------------------------------------------------*/ /* Task utilities. */ -#define portYIELD() __asm( "BRK" ) +#define portNOP() __asm( "NOP" ) +#define portYIELD() __asm( "BRK" ) #define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) do { if( xHigherPriorityTaskWoken ) vTaskSwitchContext(); } while( 0 ) -#define portNOP() __asm( "NOP" ) /*-----------------------------------------------------------*/ /* Hardwware specifics. */ -#define portBYTE_ALIGNMENT 2 -#define portSTACK_GROWTH ( -1 ) -#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 2 +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ @@ -139,7 +141,88 @@ extern volatile uint16_t usCriticalNesting; \ #ifdef __cplusplus } +#endif /* __cplusplus */ + +#endif /* __IAR_SYSTEMS_ICC__ */ + +;//----------------------------------------------------------------------------- +;// The macros below are processed for asm sources which include portmacro.h. +;//----------------------------------------------------------------------------- +#ifdef __IAR_SYSTEMS_ASM__ + +;/* Functions and variables used by this file. */ +;//----------------------------------------------------------------------------- + EXTERN _pxCurrentTCB + EXTERN _usCriticalNesting + +;/* Macro used to declutter calls, depends on the selected code model. */ +;//----------------------------------------------------------------------------- +#if __CODE_MODEL__ == __CODE_MODEL_FAR__ + #define RCALL(X) CALL F:X +#else + #define RCALL(X) CALL X #endif -#endif /* PORTMACRO_H */ +;/*----------------------------------------------------------------------------- +; * portSAVE_CONTEXT MACRO +; * Saves the context of the general purpose registers, CS and ES (only in __far +; * memory mode) registers the _usCriticalNesting value and the Stack Pointer +; * of the active Task onto the task stack. +; *---------------------------------------------------------------------------*/ +portSAVE_CONTEXT MACRO + PUSH AX ; // Save AX Register to stack. + PUSH HL +#if __CODE_MODEL__ == __CODE_MODEL_FAR__ + MOV A, CS ; // Save CS register. + XCH A, X + MOV A, ES ; // Save ES register. + PUSH AX +#else + MOV A, CS ; // Save CS register. + PUSH AX +#endif + PUSH DE ; // Save the remaining general purpose registers. + PUSH BC + MOVW AX, _usCriticalNesting ; // Save the _usCriticalNesting value. + PUSH AX + MOVW AX, _pxCurrentTCB ; // Save the Task stack pointer. + MOVW HL, AX + MOVW AX, SP + MOVW [HL], AX + ENDM +;//----------------------------------------------------------------------------- + + +;/*----------------------------------------------------------------------------- +; * portRESTORE_CONTEXT MACRO +; * Restores the task Stack Pointer then use this to restore _usCriticalNesting, +; * general purpose registers and the CS and ES (only in __far memory mode) +; * of the selected task from the task stack. +; *---------------------------------------------------------------------------*/ +portRESTORE_CONTEXT MACRO + MOVW AX, _pxCurrentTCB ; // Restore the Task stack pointer. + MOVW HL, AX + MOVW AX, [HL] + MOVW SP, AX + POP AX ; // Restore _usCriticalNesting value. + MOVW _usCriticalNesting, AX + POP BC ; // Restore the necessary general purpose registers. + POP DE +#if __CODE_MODEL__ == __CODE_MODEL_FAR__ + POP AX ; // Restore the ES register. + MOV ES, A + XCH A, X ; // Restore the CS register. + MOV CS, A +#else + POP AX + MOV CS, A ; // Restore CS register. +#endif + POP HL ; // Restore general purpose register HL. + POP AX ; // Restore AX. + ENDM +;//----------------------------------------------------------------------------- + +#endif /* __IAR_SYSTEMS_ASM__ */ + +#endif /* PORTMACRO_H */