mirror of
				https://github.com/FreeRTOS/FreeRTOS-Kernel.git
				synced 2025-11-04 02:59:01 +01:00 
			
		
		
		
	Add CC-RH port for Renesas F1Kx devices (#1100)
Add CC-RH port for Renesas F1Kx devices
This commit is contained in:
		
							parent
							
								
									c963d24001
								
							
						
					
					
						commit
						da3c35aa48
					
				
							
								
								
									
										18
									
								
								.github/.cSpellWords.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								.github/.cSpellWords.txt
									
									
									
									
										vendored
									
									
								
							@ -75,6 +75,7 @@ CCNT
 | 
			
		||||
CCNTR
 | 
			
		||||
CCPN
 | 
			
		||||
CCPR
 | 
			
		||||
CCRH
 | 
			
		||||
CDTY
 | 
			
		||||
CDTYR
 | 
			
		||||
CFBS
 | 
			
		||||
@ -86,6 +87,7 @@ CHSR
 | 
			
		||||
CICR
 | 
			
		||||
CISR
 | 
			
		||||
CKDIV
 | 
			
		||||
CKDIVMD
 | 
			
		||||
CKEY
 | 
			
		||||
CKGR
 | 
			
		||||
CKLO
 | 
			
		||||
@ -125,6 +127,7 @@ CODR
 | 
			
		||||
comms
 | 
			
		||||
COMPA
 | 
			
		||||
CONFG
 | 
			
		||||
coreid
 | 
			
		||||
coremqtt
 | 
			
		||||
CORTUS
 | 
			
		||||
coverity
 | 
			
		||||
@ -149,6 +152,7 @@ CPRE
 | 
			
		||||
cpsid
 | 
			
		||||
cpsie
 | 
			
		||||
CPSR
 | 
			
		||||
CPUCLK
 | 
			
		||||
CPUID
 | 
			
		||||
CRCB
 | 
			
		||||
crflash
 | 
			
		||||
@ -164,6 +168,8 @@ csrs
 | 
			
		||||
csrw
 | 
			
		||||
CTCR
 | 
			
		||||
ctest
 | 
			
		||||
CTPC
 | 
			
		||||
CTPSW
 | 
			
		||||
CTRLA
 | 
			
		||||
CTSIC
 | 
			
		||||
CUPD
 | 
			
		||||
@ -227,6 +233,7 @@ DTREN
 | 
			
		||||
DTXD
 | 
			
		||||
DUNITY
 | 
			
		||||
DVAR
 | 
			
		||||
Dxxx
 | 
			
		||||
EABI
 | 
			
		||||
ecall
 | 
			
		||||
ECIT
 | 
			
		||||
@ -237,6 +244,7 @@ EEVT
 | 
			
		||||
eevtedg
 | 
			
		||||
EEVTEDG
 | 
			
		||||
EFRHD
 | 
			
		||||
EIIC
 | 
			
		||||
EINT
 | 
			
		||||
EIPC
 | 
			
		||||
EIPSW
 | 
			
		||||
@ -310,6 +318,7 @@ FNTR
 | 
			
		||||
FOSC
 | 
			
		||||
FPCCR
 | 
			
		||||
FPCSR
 | 
			
		||||
FPEPC
 | 
			
		||||
FPSW
 | 
			
		||||
FPUL
 | 
			
		||||
FRDY
 | 
			
		||||
@ -338,6 +347,7 @@ GPTA
 | 
			
		||||
HCLK
 | 
			
		||||
Hitach
 | 
			
		||||
HRESP
 | 
			
		||||
HTCFG
 | 
			
		||||
HWHSH
 | 
			
		||||
HWORD
 | 
			
		||||
HWRD
 | 
			
		||||
@ -353,6 +363,7 @@ ICCR
 | 
			
		||||
ICCRPR
 | 
			
		||||
ICCRX
 | 
			
		||||
ICERST
 | 
			
		||||
ICIPI
 | 
			
		||||
ICSR
 | 
			
		||||
IDCR
 | 
			
		||||
IECR
 | 
			
		||||
@ -372,6 +383,7 @@ INTTM
 | 
			
		||||
IODEFINE
 | 
			
		||||
IORLW
 | 
			
		||||
IPEN
 | 
			
		||||
IPIR
 | 
			
		||||
IPLB
 | 
			
		||||
ipsr
 | 
			
		||||
IPSR
 | 
			
		||||
@ -380,8 +392,8 @@ IRET
 | 
			
		||||
IRXFCS
 | 
			
		||||
ISRAM
 | 
			
		||||
ISRR
 | 
			
		||||
ISR's
 | 
			
		||||
ISRS
 | 
			
		||||
ISR's
 | 
			
		||||
ISRTICK
 | 
			
		||||
isystem
 | 
			
		||||
ITIF
 | 
			
		||||
@ -564,6 +576,7 @@ OSCEN
 | 
			
		||||
OSCOFF
 | 
			
		||||
OSCOUNT
 | 
			
		||||
OSMC
 | 
			
		||||
OSTM
 | 
			
		||||
outpw
 | 
			
		||||
OVLY
 | 
			
		||||
OVRE
 | 
			
		||||
@ -584,6 +597,7 @@ PCLKSEL
 | 
			
		||||
PCSR
 | 
			
		||||
PCXI
 | 
			
		||||
PDSR
 | 
			
		||||
PEID
 | 
			
		||||
PEIE
 | 
			
		||||
PENDSV
 | 
			
		||||
PENDSVCLEAR
 | 
			
		||||
@ -799,6 +813,8 @@ SWINTR
 | 
			
		||||
SWRST
 | 
			
		||||
SWTRG
 | 
			
		||||
synchronise
 | 
			
		||||
SYNCM
 | 
			
		||||
syncm
 | 
			
		||||
SYSC
 | 
			
		||||
sysclk
 | 
			
		||||
Sysclk
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										46
									
								
								portable/CCRH/F1Kx/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								portable/CCRH/F1Kx/README.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,46 @@
 | 
			
		||||
# RH850/F1K and F1Kx FreeRTOS Port with CC-RH Compiler
 | 
			
		||||
 | 
			
		||||
## Introduction
 | 
			
		||||
 | 
			
		||||
This repository contains the port of FreeRTOS for Renesas RH850/F1K and F1Kx microcontrollers using the CC-RH compiler. The following sections provide instructions on how to use this port, a link to the test project, and other relevant information.
 | 
			
		||||
 | 
			
		||||
## Prerequisites
 | 
			
		||||
- Compiler: CC-RH
 | 
			
		||||
- FreeRTOS version 11.1.0
 | 
			
		||||
 | 
			
		||||
| Device   | FPU | SMP |
 | 
			
		||||
|----------|-----|-----|
 | 
			
		||||
| F1K      | Yes | No  |
 | 
			
		||||
| F1KM-S1  | Yes | No  |
 | 
			
		||||
| F1KM-S2  | Yes | No  |
 | 
			
		||||
| F1KM-S4  | Yes | No  |
 | 
			
		||||
| F1KH-D8  | Yes | Yes |
 | 
			
		||||
 | 
			
		||||
## Link to Test Project
 | 
			
		||||
 | 
			
		||||
The test project can be found [here](https://github.com/FreeRTOS/FreeRTOS-Community-Supported-Demos) (`RH850_F1Kx_CCRH`). This project contains example tasks and configurations to help you get started with FreeRTOS on the RH850/F1K and F1Kx.
 | 
			
		||||
 | 
			
		||||
## Note
 | 
			
		||||
   1. Configure IPIR Interrupt: Ensure that the bit specifying the destination for binding (requesting) an interrupt is enabled (e.g: IBDxxx register of F1KH-D8) (1)
 | 
			
		||||
   2. `Channel 0` and address `0xFFFEEC00` are used as default configuration for configIPIR_CHANNEL and configEXCLUSIVE_ADDRESS, in case of resource confliction other channel/address can be used. (2)
 | 
			
		||||
   3. The minimal stack size (configMINIMAL_STACK_SIZE) must be included the reserved memory for nested interrupt. This formula can be referred: `(task_context_size) * (1 + configMAX_INT_NESTING) + Stack_depth_of_taskcode`
 | 
			
		||||
   In which, `task_context_size` is calculated as `36*4bytes = 144bytes` (when FPU enabled) or `34*4bytes = 136` (when FPU disabled), configMAX_INT_NESTING is 02 as default.
 | 
			
		||||
   4. `configTIMER_PRESCALE`: This value is required in order to correctly configure clock for `CPUCLK_L`. Refer to Hardware Manual at `Table 44.22` for `option byte`: If the user sets the option byte `CKDIVMD to 1`, then `configTIMER_PRESCALE = 4`. Otherwise, if `CKDIVMD is set to 0`, then `configTIMER_PRESCALE = 2`.
 | 
			
		||||
 | 
			
		||||
(1)  This is applicable for F1KH-D8 with SMP only.
 | 
			
		||||
 | 
			
		||||
(2) This is optional and applicable for SMP only.
 | 
			
		||||
 | 
			
		||||
## Other Relevant Information
 | 
			
		||||
 | 
			
		||||
- **Documentation:**
 | 
			
		||||
  - Refer to the official [FreeRTOS documentation](https://www.freertos.org/Documentation/RTOS_book.html) for detailed information on configuring and using FreeRTOS.
 | 
			
		||||
  - Consult the [RH850 F1K group user manual hardware manual](https://www.renesas.com/us/en/document/mah/rh850f1k-group-users-manual-hardware?r=1170166) for specific details about the microcontroller.
 | 
			
		||||
  - For more information about Renesas RH850/F1K and F1Kx, please visit [this website](https://www.renesas.com/us/en/products/microcontrollers-microprocessors/rh850-automotive-mcus)
 | 
			
		||||
  - The CC-RH compiler can be downloaded [here](https://www.renesas.com/us/en/software-tool/c-compiler-package-rh850-family#downloads)
 | 
			
		||||
 | 
			
		||||
- **Support:**
 | 
			
		||||
  - If you encounter any issues or have questions about this port, please open an issue in this repository or contact the maintainer.
 | 
			
		||||
 | 
			
		||||
- **Contributing:**
 | 
			
		||||
  - Contributions to improve this port are welcome. Please fork the repository, make your changes, and submit a pull request.
 | 
			
		||||
							
								
								
									
										734
									
								
								portable/CCRH/F1Kx/port.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										734
									
								
								portable/CCRH/F1Kx/port.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,734 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel <DEVELOPMENT BRANCH>
 | 
			
		||||
 * 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
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Scheduler includes. */
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
 | 
			
		||||
/* This port uses xTaskGetCurrentTaskHandle to get TCB stack, it is required to
 | 
			
		||||
 * enable this API. */
 | 
			
		||||
#if ( ( INCLUDE_xTaskGetCurrentTaskHandle != 1 ) && ( configNUMBER_OF_CORES == 1 ) )
 | 
			
		||||
    #error INCLUDE_xTaskGetCurrentTaskHandle must be set to 1 in single core.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/***********************************************************
 | 
			
		||||
* Macro definitions
 | 
			
		||||
***********************************************************/
 | 
			
		||||
 | 
			
		||||
/* Hardware specific macros */
 | 
			
		||||
#define portPSW_REGISTER_ID          ( 5 )
 | 
			
		||||
#define portFPSR_REGISTER_ID         ( 6 )
 | 
			
		||||
 | 
			
		||||
/* PSW.EBV and PSW.CUx bits are kept as current status */
 | 
			
		||||
#define portINITIAL_PSW_MASK         ( 0x000f8000 )
 | 
			
		||||
#define portCURRENT_PSW_VALUE        ( portSTSR( portPSW_REGISTER_ID ) )
 | 
			
		||||
#define portCURRENT_SR_ZERO_VALUE    ( ( StackType_t ) 0x00000000 )
 | 
			
		||||
#define portCURRENT_FPSR_VALUE       ( portSTSR( portFPSR_REGISTER_ID ) )
 | 
			
		||||
 | 
			
		||||
/* Mask for FPU configuration bits (FN, PEM, RM, FS) */
 | 
			
		||||
#define portINITIAL_FPSR_MASK        ( 0x00ae0000 )
 | 
			
		||||
#define portPSW_ID_MASK              ( 0x00000020 )
 | 
			
		||||
 | 
			
		||||
/* Define necessary hardware IO for OSTM timer. OSTM0 is used by default as
 | 
			
		||||
 * it is common for almost device variants. If it conflicts with application,
 | 
			
		||||
 * the application shall implement another timer.*/
 | 
			
		||||
#define portOSTM_EIC_ADDR            ( 0xFFFFB0A8 )
 | 
			
		||||
#define portOSTM0CMP_ADDR            ( 0xFFD70000 )
 | 
			
		||||
#define portOSTM0CTL_ADDR            ( 0xFFD70020 )
 | 
			
		||||
#define portOSTM0TS_ADDR             ( 0xFFD70014 )
 | 
			
		||||
 | 
			
		||||
#if ( configNUMBER_OF_CORES > 1 )
 | 
			
		||||
 | 
			
		||||
/* IPIR  base address, the peripheral is used for Inter-Processor communication
 | 
			
		||||
 * Hardware supports 4 channels which is offset by 0x0, 0x4, 0x8, 0xC bytes from
 | 
			
		||||
 * base address. By default, channel 0 is selected. */
 | 
			
		||||
    #ifdef configIPIR_CHANNEL
 | 
			
		||||
        #define portIPIR_BASE_ADDR    ( ( 0xFFFEEC80 ) + ( configIPIR_CHANNEL << 2 ) )
 | 
			
		||||
    #else
 | 
			
		||||
        #define portIPIR_BASE_ADDR    ( 0xFFFEEC80 )
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
/*  Address used for exclusive control for variable shared between PEs
 | 
			
		||||
 * (common resources), each CPU cores have independent access path to
 | 
			
		||||
 * this address. By default, G0MEV0 register is selected*/
 | 
			
		||||
    #ifdef configEXCLUSIVE_ADDRESS
 | 
			
		||||
        #define portMEV_BASE_ADDR    configEXCLUSIVE_ADDRESS
 | 
			
		||||
    #else
 | 
			
		||||
        #define portMEV_BASE_ADDR    ( 0xFFFEEC00 )
 | 
			
		||||
    #endif
 | 
			
		||||
#endif /* if ( configNUMBER_OF_CORES > 1 ) */
 | 
			
		||||
 | 
			
		||||
/* Macros required to set up the initial stack. */
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R1     ( ( StackType_t ) 0x01010101 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R2     ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x02 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R3     ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x03 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R4     ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x04 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R5     ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x05 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R6     ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x06 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R7     ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x07 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R8     ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x08 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R9     ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x09 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R10    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x10 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R11    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x11 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R12    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x12 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R13    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x13 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R14    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x14 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R15    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x15 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R16    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x16 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R17    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x17 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R18    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x18 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R19    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x19 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R20    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x20 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R21    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x21 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R22    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x22 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R23    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x23 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R24    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x24 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R25    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x25 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R26    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x26 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R27    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x27 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R28    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x28 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R29    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x29 )
 | 
			
		||||
#define portSTACK_INITIAL_VALUE_R30    ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x30 )
 | 
			
		||||
 | 
			
		||||
/***********************************************************
 | 
			
		||||
* Typedef definitions
 | 
			
		||||
***********************************************************/
 | 
			
		||||
 | 
			
		||||
/* OSTM Count Start Trigger Register (OSTMnTS) */
 | 
			
		||||
#define portOSTM_COUNTER_START              ( 0x01U ) /* Starts the counter */
 | 
			
		||||
 | 
			
		||||
/* OSTM Count Stop Trigger Register (OSTMnTT) */
 | 
			
		||||
#define portOSTM_COUNTER_STOP               ( 0x01U ) /* Stops the counter */
 | 
			
		||||
 | 
			
		||||
/* OSTM Control Register (OSTMnCTL) */
 | 
			
		||||
#define portOSTM_MODE_INTERVAL_TIMER        ( 0x00U )
 | 
			
		||||
#define portOSTM_MODE_FREE_RUNNING          ( 0x02U )
 | 
			
		||||
 | 
			
		||||
/* Disables or Enable the interrupts when counting starts */
 | 
			
		||||
#define portOSTM_START_INTERRUPT_DISABLE    ( 0x00U )
 | 
			
		||||
#define portOSTM_START_INTERRUPT_ENABLE     ( 0x01U )
 | 
			
		||||
 | 
			
		||||
/* Interrupt vector method select (TBxxx) */
 | 
			
		||||
#define portINT_DIRECT_VECTOR               ( 0x0U )
 | 
			
		||||
#define portINT_TABLE_VECTOR                ( 0x1U )
 | 
			
		||||
 | 
			
		||||
/* Interrupt mask (MKxxx) */
 | 
			
		||||
#define portINT_PROCESSING_ENABLED          ( 0x0U )
 | 
			
		||||
#define portINT_PROCESSING_DISABLED         ( 0x1U )
 | 
			
		||||
 | 
			
		||||
/* Specify 16 interrupt priority levels */
 | 
			
		||||
#define portINT_PRIORITY_HIGHEST            ( 0x0000U ) /* Level 0 (highest) */
 | 
			
		||||
#define portINT_PRIORITY_LEVEL1             ( 0x0001U ) /* Level 1 */
 | 
			
		||||
#define portINT_PRIORITY_LEVEL2             ( 0x0002U ) /* Level 2 */
 | 
			
		||||
#define portINT_PRIORITY_LEVEL3             ( 0x0003U ) /* Level 3 */
 | 
			
		||||
#define portINT_PRIORITY_LEVEL4             ( 0x0004U ) /* Level 4 */
 | 
			
		||||
#define portINT_PRIORITY_LEVEL5             ( 0x0005U ) /* Level 5 */
 | 
			
		||||
#define portINT_PRIORITY_LEVEL6             ( 0x0006U ) /* Level 6 */
 | 
			
		||||
#define portINT_PRIORITY_LEVEL7             ( 0x0007U ) /* Level 7 */
 | 
			
		||||
#define portINT_PRIORITY_LEVEL8             ( 0x0008U ) /* Level 8 */
 | 
			
		||||
#define portINT_PRIORITY_LEVEL9             ( 0x0009U ) /* Level 9 */
 | 
			
		||||
#define portINT_PRIORITY_LEVEL10            ( 0x000AU ) /* Level 10 */
 | 
			
		||||
#define portINT_PRIORITY_LEVEL11            ( 0x000BU ) /* Level 11 */
 | 
			
		||||
#define portINT_PRIORITY_LEVEL12            ( 0x000CU ) /* Level 12 */
 | 
			
		||||
#define portINT_PRIORITY_LEVEL13            ( 0x000DU ) /* Level 13 */
 | 
			
		||||
#define portINT_PRIORITY_LEVEL14            ( 0x000EU ) /* Level 14 */
 | 
			
		||||
#define portINT_PRIORITY_LOWEST             ( 0x000FU ) /* Level 15 (lowest) */
 | 
			
		||||
 | 
			
		||||
/* Macros indicating status of scheduler request */
 | 
			
		||||
#define PORT_SCHEDULER_NOREQUEST            0UL
 | 
			
		||||
#define PORT_SCHEDULER_TASKSWITCH           1UL       /* Do not modify */
 | 
			
		||||
#define PORT_SCHEDULER_STARTFIRSTTASK       2UL       /* Do not modify */
 | 
			
		||||
 | 
			
		||||
#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 */
 | 
			
		||||
 | 
			
		||||
#ifndef configMAX_INT_NESTING
 | 
			
		||||
 | 
			
		||||
/* Set the default value for depth of nested interrupt. In theory, the
 | 
			
		||||
 * microcontroller have mechanism to limit number of nested level of interrupt
 | 
			
		||||
 * by priority (maximum 16 levels). However, the large stack memory should be
 | 
			
		||||
 * prepared for each task to save resource in interrupt handler. Therefore, it
 | 
			
		||||
 * is necessary to limit depth of nesting interrupt to optimize memory usage.
 | 
			
		||||
 * In addition, the execution time of interrupt handler should be very short
 | 
			
		||||
 * (typically not exceed 20us), this constraint does not impact to system.
 | 
			
		||||
 */
 | 
			
		||||
    #define configMAX_INT_NESTING    2UL
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Used to catch tasks that attempt to return from their implementing function.
 | 
			
		||||
 */
 | 
			
		||||
static void prvTaskExitError( void );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Sets up the periodic ISR used for the RTOS tick using the OSTM.
 | 
			
		||||
 * The application writer can define configSETUP_TICK_INTERRUPT() (in
 | 
			
		||||
 * FreeRTOSConfig.h) such that their own tick interrupt configuration is used
 | 
			
		||||
 * in place of prvSetupTimerInterrupt().
 | 
			
		||||
 */
 | 
			
		||||
static void prvSetupTimerInterrupt( void );
 | 
			
		||||
 | 
			
		||||
#if ( configNUMBER_OF_CORES > 1 )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Functions implement spin-lock between cores by atomic accesses to Exclusive
 | 
			
		||||
 * Control Register (G0MEVm). There are separated access path between CPU cores,
 | 
			
		||||
 * but they should wait if access to same register
 | 
			
		||||
 */
 | 
			
		||||
    static void prvExclusiveLock( BaseType_t xFromIsr );
 | 
			
		||||
    static void prvExclusiveRelease( BaseType_t xFromIsr );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Function to start the first task executing
 | 
			
		||||
 */
 | 
			
		||||
extern void vPortStartFirstTask( void );
 | 
			
		||||
 | 
			
		||||
/* Scheduler request on each cores which are starting first task and switching
 | 
			
		||||
 * context */
 | 
			
		||||
volatile BaseType_t xPortScheduleStatus[ configNUMBER_OF_CORES ] = { 0 };
 | 
			
		||||
 | 
			
		||||
/* Counts the interrupt nesting depth. A context switch is only performed if
 | 
			
		||||
 * the nesting depth is 0. In addition, the interrupt shares same stack
 | 
			
		||||
 * allocated for each tasks. With supporting nesting interrupt, the stack
 | 
			
		||||
 * may be overflowed.
 | 
			
		||||
 * It is necessary to control maximum stack depth.
 | 
			
		||||
 */
 | 
			
		||||
volatile UBaseType_t uxInterruptNesting[ configNUMBER_OF_CORES ] = { 0 };
 | 
			
		||||
volatile const UBaseType_t uxPortMaxInterruptDepth = configMAX_INT_NESTING - 1;
 | 
			
		||||
 | 
			
		||||
/* Count number of nested locks by same cores. The lock is completely released
 | 
			
		||||
 * only if this count is decreased to 0, the lock is separated for task
 | 
			
		||||
 * and isr */
 | 
			
		||||
UBaseType_t uxLockNesting[ configNUMBER_OF_CORES ][ 2 ] = { 0 };
 | 
			
		||||
 | 
			
		||||
#if ( configNUMBER_OF_CORES > 1 )
 | 
			
		||||
 | 
			
		||||
/* Pointer to exclusive access memory */
 | 
			
		||||
    volatile BaseType_t * pxPortExclusiveReg = ( volatile BaseType_t * ) ( portMEV_BASE_ADDR );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Interrupt handler for OSTM timer which handling tick increment and resulting
 | 
			
		||||
 * to switch context. */
 | 
			
		||||
void vPortTickISR( void );
 | 
			
		||||
 | 
			
		||||
#if ( configNUMBER_OF_CORES > 1 )
 | 
			
		||||
 | 
			
		||||
/* Yield specific cores by send inter-processor interrupt */
 | 
			
		||||
    void vPortYieldCore( uint32_t xCoreID );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Inter-processor interrupt handler. The interrupt is triggered by
 | 
			
		||||
 * portYIELD_CORE().
 | 
			
		||||
 */
 | 
			
		||||
    void vPortIPIHander( void );
 | 
			
		||||
 | 
			
		||||
/* These functions below implement recursive spinlock for exclusive access among
 | 
			
		||||
 * cores. The core will wait until lock will be available, whilst the core which
 | 
			
		||||
 * already had lock can acquire lock without waiting. This function could be
 | 
			
		||||
 * call from task and interrupt context, the critical section is called
 | 
			
		||||
 * as in ISR */
 | 
			
		||||
    void vPortRecursiveLockAcquire( BaseType_t xFromIsr );
 | 
			
		||||
    void vPortRecursiveLockRelease( BaseType_t xFromIsr );
 | 
			
		||||
 | 
			
		||||
#endif /* (configNUMBER_OF_CORES > 1) */
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * These below functions implement interrupt mask from interrupt. They are not
 | 
			
		||||
 * called in nesting, it is protected by FreeRTOS kernel.
 | 
			
		||||
 */
 | 
			
		||||
portLONG xPortSetInterruptMask( void )
 | 
			
		||||
{
 | 
			
		||||
    portLONG ulPSWValue = portSTSR( portPSW_REGISTER_ID );
 | 
			
		||||
 | 
			
		||||
    portDISABLE_INTERRUPTS();
 | 
			
		||||
 | 
			
		||||
    /* It returns current value of Program Status Word register */
 | 
			
		||||
    return ulPSWValue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortClearInterruptMask( portLONG uxSavedInterruptStatus )
 | 
			
		||||
{
 | 
			
		||||
    portLONG ulPSWValue = portSTSR( portPSW_REGISTER_ID );
 | 
			
		||||
 | 
			
		||||
    /* Interrupt Disable status is indicates by bit#5 of PSW
 | 
			
		||||
    * (1: Interrupt is disabled; 0: Interrupt is enabled) */
 | 
			
		||||
 | 
			
		||||
    /* Revert to the status before interrupt mask. */
 | 
			
		||||
    ulPSWValue &= ( ~( portPSW_ID_MASK ) );
 | 
			
		||||
    ulPSWValue |= ( portPSW_ID_MASK & uxSavedInterruptStatus );
 | 
			
		||||
    portLDSR( portPSW_REGISTER_ID, ulPSWValue );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Using CC-RH intrinsic function to get HTCFG0 (regID, selID) = (0,2)
 | 
			
		||||
 * Core ID is indicates by bit HTCFG0.PEID located at bit 18 to 16
 | 
			
		||||
 * Bit 31 to 19 are read only and always be read as 0. HTCFG0.PEID is 1 and 2
 | 
			
		||||
 * corresponding to core 0 (PE1) and core 1 (PE2). It is adjusted to 0 and 1.
 | 
			
		||||
 */
 | 
			
		||||
BaseType_t xPortGET_CORE_ID( void )
 | 
			
		||||
{
 | 
			
		||||
    #if ( configNUMBER_OF_CORES > 1 )
 | 
			
		||||
        return ( portSTSR_CCRH( 0, 2 ) >> 16 ) - 1;
 | 
			
		||||
    #else
 | 
			
		||||
 | 
			
		||||
        /* In single core, xPortGET_CORE_ID is used in this port only.
 | 
			
		||||
         * The dummy core ID could be controlled inside this port. */
 | 
			
		||||
        return 0;
 | 
			
		||||
    #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This port supports both multi-cores and single-core, whilst TCB stack
 | 
			
		||||
 * variables are different which are respectively pxCurrentTCB (single-core)
 | 
			
		||||
 * and pxCurrentTCBs[] (multiple-cores). This function is defined to obtains
 | 
			
		||||
 * TCBs of current cores. Also, the C function could switch to corresponding
 | 
			
		||||
 * pointer by pre-compile conditions.
 | 
			
		||||
 */
 | 
			
		||||
void * pvPortGetCurrentTCB( void )
 | 
			
		||||
{
 | 
			
		||||
    void * pvCurrentTCB = ( void * ) xTaskGetCurrentTaskHandle();
 | 
			
		||||
 | 
			
		||||
    configASSERT( pvCurrentTCB != NULL );
 | 
			
		||||
 | 
			
		||||
    return pvCurrentTCB;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This function checks if a context switch is required and, if so, updates
 | 
			
		||||
 * the scheduler status for the core on which the function is called. The
 | 
			
		||||
 * scheduler status is set to indicate that a task switch should occur.
 | 
			
		||||
 */
 | 
			
		||||
void vPortSetSwitch( BaseType_t xSwitchRequired )
 | 
			
		||||
{
 | 
			
		||||
    if( xSwitchRequired != pdFALSE )
 | 
			
		||||
    {
 | 
			
		||||
        xPortScheduleStatus[ xPortGET_CORE_ID() ] = PORT_SCHEDULER_TASKSWITCH;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]  pxTopOfStack  Pointer to top of this task's stack
 | 
			
		||||
 * @param[in]  pxCode        Task function, stored as initial PC for the task
 | 
			
		||||
 * @param[in]  pvParameters  Parameters for task
 | 
			
		||||
 */
 | 
			
		||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
 | 
			
		||||
                                     TaskFunction_t pxCode,
 | 
			
		||||
                                     void * pvParameters )
 | 
			
		||||
{
 | 
			
		||||
    /* Simulate the stack frame as it would be created by
 | 
			
		||||
     * a context switch interrupt. */
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) prvTaskExitError;            /* R31 (LP) */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R5;  /* R5 (TP)  */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) pvParameters;                /* R6       */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R7;  /* R7       */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R8;  /* R8       */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R9;  /* R9       */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R10; /* R10      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R11; /* R11      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R12; /* R12      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R13; /* R13      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R14; /* R14      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R15; /* R15      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R16; /* R16      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R17; /* R17      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R18; /* R18      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R19; /* R19      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R20; /* R20      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R21; /* R21      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R22; /* R22      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R23; /* R23      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R24; /* R24      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R25; /* R25      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R26; /* R26      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R27; /* R27      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R28; /* R28      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R29; /* R29      */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R30; /* R30 (EP) */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R1;  /* R1        */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R2;  /* R2        */
 | 
			
		||||
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
 | 
			
		||||
    /* Keep System pre-configuration (HV, CUx, EBV) as current setting in
 | 
			
		||||
     * PSW register */
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) ( portCURRENT_PSW_VALUE & portINITIAL_PSW_MASK ); /* EIPSW */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) pxCode;                                           /* EIPC */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE;                        /* EIIC */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) ( portCURRENT_PSW_VALUE & portINITIAL_PSW_MASK ); /* CTPSW */
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE;                        /* CTPC */
 | 
			
		||||
 | 
			
		||||
/* __FPU is defined by CCRH compiler if FPU is enabled */
 | 
			
		||||
    #if ( configENABLE_FPU == 1 )
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
        *pxTopOfStack = ( StackType_t ) ( portCURRENT_FPSR_VALUE & portINITIAL_FPSR_MASK ); /* FPSR */
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
        *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE;                          /* FPEPC */
 | 
			
		||||
    #endif /* (configENABLE_FPU == 1) */
 | 
			
		||||
 | 
			
		||||
    return pxTopOfStack;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Configures the tick frequency and starts the first task.
 | 
			
		||||
 */
 | 
			
		||||
BaseType_t xPortStartScheduler( void )
 | 
			
		||||
{
 | 
			
		||||
    #if ( configNUMBER_OF_CORES > 1 )
 | 
			
		||||
        BaseType_t xCurrentCore = xPortGET_CORE_ID();
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    /* Prevent interrupt by timer interrupt during starting first task.
 | 
			
		||||
     * The interrupt shall be enabled automatically by being restored from
 | 
			
		||||
     * task stack */
 | 
			
		||||
    portDISABLE_INTERRUPTS();
 | 
			
		||||
 | 
			
		||||
    /* Setup the tick interrupt */
 | 
			
		||||
    configSETUP_TICK_INTERRUPT();
 | 
			
		||||
 | 
			
		||||
    #if ( configNUMBER_OF_CORES > 1 )
 | 
			
		||||
        /* Start scheduler on other cores */
 | 
			
		||||
        for( uint16_t xCoreID = 0; xCoreID < configNUMBER_OF_CORES; xCoreID++ )
 | 
			
		||||
        {
 | 
			
		||||
            if( xCoreID != xCurrentCore )
 | 
			
		||||
            {
 | 
			
		||||
                /* Send yielding request to other cores with flag to start
 | 
			
		||||
                 * first task. TaskContextSwitch is not executed */
 | 
			
		||||
                xPortScheduleStatus[ xCoreID ] = PORT_SCHEDULER_STARTFIRSTTASK;
 | 
			
		||||
                vPortYieldCore( xCoreID );
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                /* Nothing to do. The first task is started in this call by
 | 
			
		||||
                 * below vPortStartFirstTask() */
 | 
			
		||||
                xPortScheduleStatus[ xCoreID ] = PORT_SCHEDULER_NOREQUEST;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    #endif /* if ( configNUMBER_OF_CORES > 1 ) */
 | 
			
		||||
 | 
			
		||||
    /* Start first task in primary core */
 | 
			
		||||
    vPortStartFirstTask();
 | 
			
		||||
 | 
			
		||||
    /* Should never get here as the tasks will now be executing! */
 | 
			
		||||
    prvTaskExitError();
 | 
			
		||||
 | 
			
		||||
    /* To prevent compiler warnings in the case that the application writer
 | 
			
		||||
     * overrides this functionality by defining configTASK_RETURN_ADDRESS.
 | 
			
		||||
     * Call vTaskSwitchContext() so link time optimization does not remove
 | 
			
		||||
     * the symbol. */
 | 
			
		||||
    vTaskSwitchContext(
 | 
			
		||||
        #if ( configNUMBER_OF_CORES > 1 )
 | 
			
		||||
            xCurrentCore
 | 
			
		||||
        #endif
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    return pdFALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Used to catch tasks that attempt to return from their implementing function.
 | 
			
		||||
 */
 | 
			
		||||
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 ).
 | 
			
		||||
     *
 | 
			
		||||
     * Artificially force an assert() to be triggered if configASSERT() is
 | 
			
		||||
     * defined, then stop here so application writers can catch the error. */
 | 
			
		||||
 | 
			
		||||
    /* This statement will always fail, triggering the assert */
 | 
			
		||||
    configASSERT( pdFALSE );
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * The following statement may be unreachable because configASSERT(pdFALSE)
 | 
			
		||||
     * always triggers an assertion failure, which typically halts program
 | 
			
		||||
     * execution.
 | 
			
		||||
     * The warning may be reported to indicate to indicate that the compiler
 | 
			
		||||
     * detects the subsequent code will not be executed.
 | 
			
		||||
     * The warning is acceptable to ensure program is halt regardless of
 | 
			
		||||
     * configASSERT(pdFALSE) implementation
 | 
			
		||||
     */
 | 
			
		||||
    portDISABLE_INTERRUPTS();
 | 
			
		||||
 | 
			
		||||
    for( ; ; )
 | 
			
		||||
    {
 | 
			
		||||
        /* Infinite loop to ensure the function does not return. */
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortEndScheduler( void )
 | 
			
		||||
{
 | 
			
		||||
    /* Not implemented in ports where there is nothing to return to.
 | 
			
		||||
     * Artificially force an assert. */
 | 
			
		||||
    configASSERT( pdFALSE );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if ( configNUMBER_OF_CORES > 1 )
 | 
			
		||||
 | 
			
		||||
    void vPortYieldCore( uint32_t xCoreID )
 | 
			
		||||
    {
 | 
			
		||||
        /* Check if we need to yield on a different core */
 | 
			
		||||
        if( xCoreID != xPortGET_CORE_ID() )
 | 
			
		||||
        {
 | 
			
		||||
            volatile uint32_t * pulIPIRReg;
 | 
			
		||||
 | 
			
		||||
            /* Determine the IPI register based on the target core ID */
 | 
			
		||||
            pulIPIRReg = ( volatile uint32_t * ) ( portIPIR_BASE_ADDR );
 | 
			
		||||
 | 
			
		||||
            /*Inter-processor interrupt generates an interrupt request by
 | 
			
		||||
             * writing 1 to applicable bits of target cores. The interrupt
 | 
			
		||||
             * should be enabled by application in  corresponding cores
 | 
			
		||||
             * including PSW.ID (EI instruction) and interrupt control setting
 | 
			
		||||
             * for ICIPIRn channel (interrupt mask, vector method)
 | 
			
		||||
             */
 | 
			
		||||
            *pulIPIRReg = ( 1 << xCoreID );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            /* Yielding current core */
 | 
			
		||||
            vPortYield();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Handler for inter-processor interrupt in second cores. The interrupt is
 | 
			
		||||
 * triggered by portYIELD_CORE(). vTaskSwitchContext() is invoked to
 | 
			
		||||
 * switch tasks
 | 
			
		||||
 */
 | 
			
		||||
    void vPortIPIHander( void )
 | 
			
		||||
    {
 | 
			
		||||
        BaseType_t xCurrentCore = xPortGET_CORE_ID();
 | 
			
		||||
 | 
			
		||||
        /* 1st execution starts 1st task, TaskSwitchContext is not executed */
 | 
			
		||||
        if( PORT_SCHEDULER_STARTFIRSTTASK != xPortScheduleStatus[ xCurrentCore ] )
 | 
			
		||||
        {
 | 
			
		||||
            xPortScheduleStatus[ xCurrentCore ] = PORT_SCHEDULER_TASKSWITCH;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#endif /* (configNUMBER_OF_CORES > 1) */
 | 
			
		||||
 | 
			
		||||
void vPortTickISR( void )
 | 
			
		||||
{
 | 
			
		||||
    /* In case of multicores with SMP,  xTaskIncrementTick is required to
 | 
			
		||||
     * called in critical section to avoid conflict resource as this function
 | 
			
		||||
     * could be called by xTaskResumeAll() from any cores. */
 | 
			
		||||
    #if ( configNUMBER_OF_CORES > 1 )
 | 
			
		||||
        BaseType_t xSavedInterruptStatus;
 | 
			
		||||
 | 
			
		||||
        xSavedInterruptStatus = portENTER_CRITICAL_FROM_ISR();
 | 
			
		||||
    #endif
 | 
			
		||||
    {
 | 
			
		||||
        /* Increment the RTOS tick. */
 | 
			
		||||
        if( xTaskIncrementTick() != pdFALSE )
 | 
			
		||||
        {
 | 
			
		||||
            /* Pend a context switch. */
 | 
			
		||||
            xPortScheduleStatus[ xPortGET_CORE_ID() ] = PORT_SCHEDULER_TASKSWITCH;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    #if ( configNUMBER_OF_CORES > 1 )
 | 
			
		||||
        portEXIT_CRITICAL_FROM_ISR( xSavedInterruptStatus );
 | 
			
		||||
    #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvSetupTimerInterrupt( void )
 | 
			
		||||
{
 | 
			
		||||
    volatile uint32_t * pulOSTMIntReg;
 | 
			
		||||
 | 
			
		||||
    /* Interrupt configuration for OSTM Timer
 | 
			
		||||
     * By default, the second lowest priority is set for timer interrupt to
 | 
			
		||||
     * avoid blocking other interrupt. Normally, user could set the lowest
 | 
			
		||||
     * priority for non-critical event. It try to keep timer on time.
 | 
			
		||||
     * In addition, direct vector table is used by default.
 | 
			
		||||
     */
 | 
			
		||||
    pulOSTMIntReg = ( volatile uint32_t * ) portOSTM_EIC_ADDR;
 | 
			
		||||
    *pulOSTMIntReg = ( portINT_PROCESSING_ENABLED | portINT_DIRECT_VECTOR | portINT_PRIORITY_LEVEL14 );
 | 
			
		||||
 | 
			
		||||
    /* Set OSTM0 control setting */
 | 
			
		||||
    *( ( volatile uint32_t * ) portOSTM0CTL_ADDR ) =
 | 
			
		||||
        ( portOSTM_MODE_INTERVAL_TIMER | portOSTM_START_INTERRUPT_DISABLE );
 | 
			
		||||
    *( ( volatile uint32_t * ) portOSTM0CMP_ADDR ) =
 | 
			
		||||
        ( ( configCPU_CLOCK_HZ / configTIMER_PRESCALE ) / configTICK_RATE_HZ ) - 1;
 | 
			
		||||
 | 
			
		||||
    /* Enable OSTM0 operation */
 | 
			
		||||
    *( ( volatile uint32_t * ) portOSTM0TS_ADDR ) = portOSTM_COUNTER_START;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if ( configNUMBER_OF_CORES > 1 )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * These functions implement spin-lock mechanism among cores using hardware
 | 
			
		||||
 * exclusive control with atomic access by CLR1 and SET1 instruction.
 | 
			
		||||
 * Nesting calls to these APIs are possible.
 | 
			
		||||
 */
 | 
			
		||||
    #pragma inline_asm prvExclusiveLock
 | 
			
		||||
    static void prvExclusiveLock( BaseType_t xBitPosition )
 | 
			
		||||
    {
 | 
			
		||||
        /* No problem with r19, CCRH does not required to restore same value
 | 
			
		||||
         * before and after function call. */
 | 
			
		||||
        mov     # _pxPortExclusiveReg, r19
 | 
			
		||||
        ld.w    0[ r19 ], r19
 | 
			
		||||
 | 
			
		||||
prvExclusiveLock_Lock:
 | 
			
		||||
 | 
			
		||||
        /* r6 is xBitPosition */
 | 
			
		||||
        set1 r6, [ r19 ]
 | 
			
		||||
        bz prvExclusiveLock_Lock_success
 | 
			
		||||
        snooze
 | 
			
		||||
        br prvExclusiveLock_Lock
 | 
			
		||||
 | 
			
		||||
prvExclusiveLock_Lock_success:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    #pragma inline_asm prvExclusiveRelease
 | 
			
		||||
    static void prvExclusiveRelease( BaseType_t xBitPosition )
 | 
			
		||||
    {
 | 
			
		||||
        mov     # _pxPortExclusiveReg, r19
 | 
			
		||||
        ld.w    0[ r19 ], r19
 | 
			
		||||
 | 
			
		||||
        /* r6 is xBitPosition */
 | 
			
		||||
        clr1 r6, [ r19 ]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
    void vPortRecursiveLockAcquire( BaseType_t xFromIsr )
 | 
			
		||||
    {
 | 
			
		||||
        BaseType_t xSavedInterruptStatus;
 | 
			
		||||
        BaseType_t xCoreID = xPortGET_CORE_ID();
 | 
			
		||||
        BaseType_t xBitPosition = ( xFromIsr == pdTRUE );
 | 
			
		||||
 | 
			
		||||
        xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
 | 
			
		||||
 | 
			
		||||
        if( uxLockNesting[ xCoreID ][ xBitPosition ] == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            prvExclusiveLock( xBitPosition );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        uxLockNesting[ xCoreID ][ xBitPosition ]++;
 | 
			
		||||
        portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void vPortRecursiveLockRelease( BaseType_t xFromIsr )
 | 
			
		||||
    {
 | 
			
		||||
        BaseType_t xSavedInterruptStatus;
 | 
			
		||||
        BaseType_t xCoreID = xPortGET_CORE_ID();
 | 
			
		||||
        BaseType_t xBitPosition = ( xFromIsr == pdTRUE );
 | 
			
		||||
 | 
			
		||||
        xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
 | 
			
		||||
 | 
			
		||||
        /* Sync memory */
 | 
			
		||||
        portSYNCM();
 | 
			
		||||
 | 
			
		||||
        /* Error check whether vPortRecursiveLockRelease() is not called in
 | 
			
		||||
         * pair with vPortRecursiveLockAcquire() */
 | 
			
		||||
        configASSERT( ( uxLockNesting[ xCoreID ][ xBitPosition ] > 0 ) );
 | 
			
		||||
        uxLockNesting[ xCoreID ][ xBitPosition ]--;
 | 
			
		||||
 | 
			
		||||
        if( uxLockNesting[ xCoreID ][ xBitPosition ] == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            prvExclusiveRelease( xBitPosition );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#endif /* (configNUMBER_OF_CORES > 1) */
 | 
			
		||||
							
								
								
									
										325
									
								
								portable/CCRH/F1Kx/portasm.s
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										325
									
								
								portable/CCRH/F1Kx/portasm.s
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,325 @@
 | 
			
		||||
;/*
 | 
			
		||||
; * FreeRTOS Kernel <DEVELOPMENT BRANCH>
 | 
			
		||||
; * 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
 | 
			
		||||
; *
 | 
			
		||||
; */
 | 
			
		||||
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
; Extern symbols
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
.extern _uxInterruptNesting
 | 
			
		||||
.extern _uxPortMaxInterruptDepth
 | 
			
		||||
.extern _xPortScheduleStatus
 | 
			
		||||
.extern _vTaskSwitchContext
 | 
			
		||||
.extern _pvPortGetCurrentTCB
 | 
			
		||||
.extern _vCommonISRHandler
 | 
			
		||||
.extern _xPortGET_CORE_ID
 | 
			
		||||
 | 
			
		||||
.public _vIrq_Handler
 | 
			
		||||
.public _vPortStartFirstTask
 | 
			
		||||
.public _vPortYield
 | 
			
		||||
.public _vTRAP0_Handler
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
; Macro definitions
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
EIPC  .set 0
 | 
			
		||||
EIPSW .set 1
 | 
			
		||||
PSW   .set 5
 | 
			
		||||
FPSR  .set 6
 | 
			
		||||
FPEPC .set 7
 | 
			
		||||
EIIC  .set 13
 | 
			
		||||
CTPC  .set 16
 | 
			
		||||
CTPSW .set 17
 | 
			
		||||
EIIC_MSK .set 0x00000FFF
 | 
			
		||||
FPU_MSK  .set 0x00010000
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
; portSAVE_CONTEXT
 | 
			
		||||
; Context saving
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
portSAVE_CONTEXT .macro
 | 
			
		||||
    prepare lp, 0
 | 
			
		||||
 | 
			
		||||
    ; Save general-purpose registers and EIPSW, EIPC, EIIC, CTPSW, CTPC into stack.
 | 
			
		||||
    pushsp  r5, r30
 | 
			
		||||
    $nowarning
 | 
			
		||||
    pushsp  r1, r2
 | 
			
		||||
    $warning
 | 
			
		||||
 | 
			
		||||
    stsr    EIPSW, r15
 | 
			
		||||
    stsr    EIPC, r16
 | 
			
		||||
    stsr    EIIC, r17
 | 
			
		||||
    stsr    CTPSW, r18
 | 
			
		||||
    stsr    CTPC, r19
 | 
			
		||||
    pushsp  r15, r19
 | 
			
		||||
 | 
			
		||||
    ; Save FPU registers to stack if FPU is enabled
 | 
			
		||||
    mov     FPU_MSK, r19
 | 
			
		||||
    tst     r15, r19
 | 
			
		||||
 | 
			
		||||
    ; Jump over next 3 instructions: stsr (4 bytes)*2 + pushsp (4 bytes)
 | 
			
		||||
    bz      12
 | 
			
		||||
    stsr    FPSR, r18
 | 
			
		||||
    stsr    FPEPC, r19
 | 
			
		||||
    pushsp  r18, r19
 | 
			
		||||
 | 
			
		||||
    ; Get current TCB, the return value is stored in r10 (CCRH compiler)
 | 
			
		||||
    jarl    _pvPortGetCurrentTCB, lp
 | 
			
		||||
    st.w    sp, 0[r10]
 | 
			
		||||
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
; portRESTORE_CONTEXT
 | 
			
		||||
; Context restoring
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
portRESTORE_CONTEXT .macro
 | 
			
		||||
    ; Current TCB is returned by r10 (CCRH compiler)
 | 
			
		||||
    jarl    _pvPortGetCurrentTCB, lp
 | 
			
		||||
    ld.w    0[r10], sp                  ; Restore the stack pointer from the TCB
 | 
			
		||||
 | 
			
		||||
    ; Restore FPU registers if FPU is enabled
 | 
			
		||||
    mov     FPU_MSK, r19
 | 
			
		||||
    stsr    PSW, r18
 | 
			
		||||
    tst     r18, r19
 | 
			
		||||
 | 
			
		||||
     ; Jump over next 3 instructions: stsr (4 bytes)*2 + popsp (4 bytes)
 | 
			
		||||
    bz      12
 | 
			
		||||
    popsp   r18, r19
 | 
			
		||||
    ldsr    r18, FPEPC
 | 
			
		||||
    ldsr    r19, FPSR
 | 
			
		||||
 | 
			
		||||
    ;Restore general-purpose registers and EIPSW, EIPC, EIIC, CTPSW, CTPC
 | 
			
		||||
    popsp   r15, r19
 | 
			
		||||
    ldsr    r19, CTPC
 | 
			
		||||
    ldsr    r18, CTPSW
 | 
			
		||||
    ldsr    r17, EIIC
 | 
			
		||||
    ldsr    r16, EIPC
 | 
			
		||||
    ldsr    r15, EIPSW
 | 
			
		||||
 | 
			
		||||
    $nowarning
 | 
			
		||||
    popsp   r1, r2
 | 
			
		||||
    $warning
 | 
			
		||||
    popsp   r5, r30
 | 
			
		||||
 | 
			
		||||
    dispose 0, lp
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
; Save used registers
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
SAVE_REGISTER .macro
 | 
			
		||||
    ; Save general-purpose registers and EIPSW, EIPC, EIIC, CTPSW, CTPC into stack.
 | 
			
		||||
    ; Callee-Save registers (r20 to r30) are not used in interrupt handler and
 | 
			
		||||
    ; guaranteed no change after function call. So, don't need to save register
 | 
			
		||||
    ; to optimize the used stack memory.
 | 
			
		||||
    pushsp  r5, r19
 | 
			
		||||
    $nowarning
 | 
			
		||||
    pushsp  r1, r2
 | 
			
		||||
    $warning
 | 
			
		||||
 | 
			
		||||
    stsr    EIPSW, r19
 | 
			
		||||
    stsr    EIPC, r18
 | 
			
		||||
    stsr    EIIC, r17
 | 
			
		||||
    mov     lp, r16
 | 
			
		||||
    mov     ep, r15
 | 
			
		||||
    stsr    CTPSW, r14
 | 
			
		||||
    stsr    CTPC, r13
 | 
			
		||||
    pushsp  r13, r19
 | 
			
		||||
 | 
			
		||||
    mov     FPU_MSK, r16
 | 
			
		||||
    tst     r16, r19
 | 
			
		||||
    bz      12
 | 
			
		||||
    stsr    FPSR, r18
 | 
			
		||||
    stsr    FPEPC, r19
 | 
			
		||||
    pushsp  r18, r19
 | 
			
		||||
 | 
			
		||||
.endm
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
; Restore used registers
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
RESTORE_REGISTER .macro
 | 
			
		||||
 | 
			
		||||
    mov     FPU_MSK, r16
 | 
			
		||||
    stsr    PSW, r18
 | 
			
		||||
    tst     r18, r19
 | 
			
		||||
    bz      12
 | 
			
		||||
    popsp   r18, r19
 | 
			
		||||
    ldsr    r18, FPEPC
 | 
			
		||||
    ldsr    r19, FPSR
 | 
			
		||||
 | 
			
		||||
    popsp   r13, r19
 | 
			
		||||
    ldsr    r13, CTPC
 | 
			
		||||
    ldsr    r14, CTPSW
 | 
			
		||||
    mov     r15, ep
 | 
			
		||||
    mov     r16, lp
 | 
			
		||||
    ldsr    r17, EIIC
 | 
			
		||||
    ldsr    r18, EIPC
 | 
			
		||||
    ldsr    r19, EIPSW
 | 
			
		||||
 | 
			
		||||
    $nowarning
 | 
			
		||||
    popsp   r1, r2
 | 
			
		||||
    $warning
 | 
			
		||||
    popsp   r5, r19
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
; Start the first task.
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
_vPortStartFirstTask:
 | 
			
		||||
    portRESTORE_CONTEXT
 | 
			
		||||
    eiret
 | 
			
		||||
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
; _vPortYield
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
_vPortYield:
 | 
			
		||||
    trap    0
 | 
			
		||||
    jmp     [lp]                        ; Return to caller function
 | 
			
		||||
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
; PortYield handler. This is installed as the TRAP exception handler.
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
_vTRAP0_Handler:
 | 
			
		||||
    ;Save the context of the current task.
 | 
			
		||||
    portSAVE_CONTEXT
 | 
			
		||||
 | 
			
		||||
    ; The use case that portYield() is called from interrupt context as nested interrupt.
 | 
			
		||||
    ; Context switch should be executed at the most outer of interrupt tree.
 | 
			
		||||
    ; In that case, set xPortScheduleStatus to flag context switch in interrupt handler.
 | 
			
		||||
    jarl    _xPortGET_CORE_ID, lp ; return value is contained in r10 (CCRH compiler)
 | 
			
		||||
    mov     r10, r11
 | 
			
		||||
    shl     2, r11
 | 
			
		||||
    mov     #_uxInterruptNesting, r19
 | 
			
		||||
    add     r11, r19
 | 
			
		||||
    ld.w    0[r19], r18
 | 
			
		||||
    cmp     r0, r18
 | 
			
		||||
    be      _vTRAP0_Handler_ContextSwitch
 | 
			
		||||
 | 
			
		||||
    mov     #_xPortScheduleStatus, r19
 | 
			
		||||
    add     r11, r19
 | 
			
		||||
 | 
			
		||||
    ; Set xPortScheduleStatus[coreID]=PORT_SCHEDULER_TASKSWITCH
 | 
			
		||||
    mov     1, r17
 | 
			
		||||
    st.w    r17, 0[r19]
 | 
			
		||||
    br      _vTRAP0_Handler_Exit
 | 
			
		||||
 | 
			
		||||
_vTRAP0_Handler_ContextSwitch:
 | 
			
		||||
    ; Pass coreID (r10) as parameter by r6 (CCRH compiler) in SMP support.
 | 
			
		||||
    mov     r10, r6
 | 
			
		||||
    ; Call the scheduler to select the next task.
 | 
			
		||||
    ; vPortYeild may be called to current core again at the end of vTaskSwitchContext.
 | 
			
		||||
    ; This may case nested interrupt, however, it is not necessary to set
 | 
			
		||||
    ; uxInterruptNesting (currently 0) for nested trap0 exception. The user interrupt
 | 
			
		||||
    ; (EI level interrupt) is not accepted inside of trap0 exception.
 | 
			
		||||
    jarl    _vTaskSwitchContext, lp
 | 
			
		||||
 | 
			
		||||
_vTRAP0_Handler_Exit:
 | 
			
		||||
    ; Restore the context of the next task to run.
 | 
			
		||||
    portRESTORE_CONTEXT
 | 
			
		||||
    eiret
 | 
			
		||||
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
; _Irq_Handler
 | 
			
		||||
; Handler interrupt service routine (ISR).
 | 
			
		||||
;------------------------------------------------------------------------------
 | 
			
		||||
_vIrq_Handler:
 | 
			
		||||
    ; Save used registers.
 | 
			
		||||
    SAVE_REGISTER
 | 
			
		||||
 | 
			
		||||
    ; Get core ID by HTCFG0, thread configuration register.
 | 
			
		||||
    ; Then, increase nesting count for current core.
 | 
			
		||||
    jarl    _xPortGET_CORE_ID, lp ; return value is contained in r10 (CCRH compiler)
 | 
			
		||||
    shl     2, r10
 | 
			
		||||
    mov     r10, r17
 | 
			
		||||
 | 
			
		||||
    mov     #_uxInterruptNesting, r19
 | 
			
		||||
    add     r17, r19
 | 
			
		||||
    ld.w    0[r19], r18
 | 
			
		||||
    addi    0x1, r18, r16
 | 
			
		||||
    st.w    r16, 0[r19]
 | 
			
		||||
 | 
			
		||||
    pushsp  r17, r19
 | 
			
		||||
 | 
			
		||||
    ;Call the interrupt handler.
 | 
			
		||||
    stsr    EIIC, r6
 | 
			
		||||
    andi    EIIC_MSK, r6, r6
 | 
			
		||||
 | 
			
		||||
    ; Do not enable interrupt for nesting. Stackover flow may occurs if the
 | 
			
		||||
    ; depth of nesting interrupt is exceeded.
 | 
			
		||||
    mov     #_uxPortMaxInterruptDepth, r15
 | 
			
		||||
    cmp     r16, r15
 | 
			
		||||
    be      4                                 ; Jump over ei instruction
 | 
			
		||||
    ei
 | 
			
		||||
    jarl    _vCommonISRHandler, lp
 | 
			
		||||
    di
 | 
			
		||||
    synce
 | 
			
		||||
 | 
			
		||||
    popsp   r17, r19
 | 
			
		||||
    st.w    r18, 0[r19]                  ; Restore the old nesting count.
 | 
			
		||||
 | 
			
		||||
    ; A context switch if no nesting interrupt.
 | 
			
		||||
    cmp     0x0, r18
 | 
			
		||||
    bne     _vIrq_Handler_NotSwitchContext
 | 
			
		||||
 | 
			
		||||
    ; Check if context switch is requested.
 | 
			
		||||
    mov     #_xPortScheduleStatus, r19
 | 
			
		||||
    add     r17, r19
 | 
			
		||||
    ld.w    0[r19], r18
 | 
			
		||||
    cmp     r0, r18
 | 
			
		||||
    bne     _vIrq_Handler_SwitchContext
 | 
			
		||||
 | 
			
		||||
_vIrq_Handler_NotSwitchContext:
 | 
			
		||||
    ; No context switch.  Restore used registers
 | 
			
		||||
    RESTORE_REGISTER
 | 
			
		||||
    eiret
 | 
			
		||||
 | 
			
		||||
;This sequence is executed for primary core only to switch context
 | 
			
		||||
_vIrq_Handler_SwitchContext:
 | 
			
		||||
    ; Clear the context switch pending flag.
 | 
			
		||||
    st.w r0, 0[r19]
 | 
			
		||||
 | 
			
		||||
    add     -1, r18
 | 
			
		||||
    bnz     _vIrq_Handler_StartFirstTask
 | 
			
		||||
    ; Restore used registers before saving the context to the task stack.
 | 
			
		||||
    RESTORE_REGISTER
 | 
			
		||||
    portSAVE_CONTEXT
 | 
			
		||||
 | 
			
		||||
    ; Get Core ID and pass to vTaskSwitchContext as parameter (CCRH compiler)
 | 
			
		||||
    ; The parameter is  unused in single core, no problem with this redudant setting
 | 
			
		||||
    jarl    _xPortGET_CORE_ID, lp ; return value is contained in r10 (CCRH compiler)
 | 
			
		||||
    mov     r10, r6
 | 
			
		||||
 | 
			
		||||
    ; vPortYeild may be called to current core again at the end of vTaskSwitchContext.
 | 
			
		||||
    ; This may case nested interrupt, however, it is not necessary to set
 | 
			
		||||
    ; uxInterruptNesting (currently 0) for  trap0 exception. The user interrupt
 | 
			
		||||
    ; (EI level interrupt) is not accepted inside of trap0 exception.
 | 
			
		||||
    jarl    _vTaskSwitchContext, lp    ;
 | 
			
		||||
    portRESTORE_CONTEXT
 | 
			
		||||
    eiret
 | 
			
		||||
 | 
			
		||||
_vIrq_Handler_StartFirstTask:
 | 
			
		||||
    RESTORE_REGISTER
 | 
			
		||||
    jr _vPortStartFirstTask
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										193
									
								
								portable/CCRH/F1Kx/portmacro.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								portable/CCRH/F1Kx/portmacro.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,193 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel <DEVELOPMENT BRANCH>
 | 
			
		||||
 * 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 PORTMACRO_H
 | 
			
		||||
    #define PORTMACRO_H
 | 
			
		||||
 | 
			
		||||
    #ifdef __cplusplus
 | 
			
		||||
        extern "C"
 | 
			
		||||
        {
 | 
			
		||||
    #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 - These are a bit legacy and not really used now, other
 | 
			
		||||
 * than portSTACK_TYPE and portBASE_TYPE. */
 | 
			
		||||
    #define portCHAR          char
 | 
			
		||||
    #define portFLOAT         float
 | 
			
		||||
    #define portDOUBLE        double
 | 
			
		||||
    #define portLONG          long
 | 
			
		||||
    #define portSHORT         short
 | 
			
		||||
    #define portSTACK_TYPE    uint32_t
 | 
			
		||||
    #define portBASE_TYPE     long
 | 
			
		||||
 | 
			
		||||
    typedef portSTACK_TYPE   StackType_t;
 | 
			
		||||
    typedef long             BaseType_t;
 | 
			
		||||
    typedef unsigned long    UBaseType_t;
 | 
			
		||||
 | 
			
		||||
/* Defines the maximum time when using a wait command in a task */
 | 
			
		||||
    #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
 | 
			
		||||
        typedef uint16_t     TickType_t;
 | 
			
		||||
        #define portMAX_DELAY              ( TickType_t ) 0xffff
 | 
			
		||||
    #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
 | 
			
		||||
        typedef uint32_t     TickType_t;
 | 
			
		||||
        #define portMAX_DELAY              ( TickType_t ) 0xffffffffUL
 | 
			
		||||
 | 
			
		||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
 | 
			
		||||
 * not need to be guarded with a critical section. */
 | 
			
		||||
        #define portTICK_TYPE_IS_ATOMIC    1
 | 
			
		||||
    #else
 | 
			
		||||
        #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* Architecture specifics */
 | 
			
		||||
 | 
			
		||||
    #define portSTSR( reg )              __stsr( ( reg ) )
 | 
			
		||||
    #define portLDSR( reg, val )         __ldsr( ( reg ), ( val ) )
 | 
			
		||||
    #define portSTSR_CCRH( reg, sel )    __stsr_rh( ( reg ), ( sel ) )
 | 
			
		||||
    #define portSYNCM()                  __syncm()
 | 
			
		||||
 | 
			
		||||
/* Determine the descending of the stack from high address to address */
 | 
			
		||||
    #define portSTACK_GROWTH      ( -1 )
 | 
			
		||||
 | 
			
		||||
/* Determine the time (in milliseconds) corresponding to each tick */
 | 
			
		||||
    #define portTICK_PERIOD_MS    ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
 | 
			
		||||
 | 
			
		||||
/* It is a multiple of 4 (the two lower-order bits of the address = 0),
 | 
			
		||||
 * otherwise it will cause MAE (Misaligned Exception) according to the manual */
 | 
			
		||||
    #define portBYTE_ALIGNMENT    ( 4 )
 | 
			
		||||
 | 
			
		||||
/* Interrupt control macros. */
 | 
			
		||||
 | 
			
		||||
    #define portENABLE_INTERRUPTS()     __EI() /* Macro to enable all maskable interrupts. */
 | 
			
		||||
    #define portDISABLE_INTERRUPTS()    __DI() /* Macro to disable all maskable interrupts. */
 | 
			
		||||
    #define taskENABLE_INTERRUPTS()     portENABLE_INTERRUPTS()
 | 
			
		||||
    #define taskDISABLE_INTERRUPTS()    portDISABLE_INTERRUPTS()
 | 
			
		||||
 | 
			
		||||
/* SMP build which means configNUM_CORES is relevant */
 | 
			
		||||
    #define portSUPPORT_SMP              1
 | 
			
		||||
 | 
			
		||||
    #define portMAX_CORE_COUNT           2
 | 
			
		||||
    #ifndef configNUMBER_OF_CORES
 | 
			
		||||
        #define configNUMBER_OF_CORES    1
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
/* Scheduler utilities */
 | 
			
		||||
 | 
			
		||||
/* Called at the end of an ISR that can cause a context switch */
 | 
			
		||||
    extern void vPortSetSwitch( BaseType_t vPortSetSwitch );
 | 
			
		||||
 | 
			
		||||
    #define portEND_SWITCHING_ISR( xSwitchRequired )    vPortSetSwitch( vPortSetSwitch )
 | 
			
		||||
 | 
			
		||||
    #define portYIELD_FROM_ISR( x )                     portEND_SWITCHING_ISR( x )
 | 
			
		||||
 | 
			
		||||
/* Use to transfer control from one task to perform other tasks of
 | 
			
		||||
 * higher priority */
 | 
			
		||||
    extern void vPortYield( void );
 | 
			
		||||
 | 
			
		||||
    #define portYIELD()    vPortYield()
 | 
			
		||||
    #if ( configNUMBER_OF_CORES > 1 )
 | 
			
		||||
 | 
			
		||||
/* Return the core ID on which the code is running. */
 | 
			
		||||
        extern BaseType_t xPortGET_CORE_ID();
 | 
			
		||||
 | 
			
		||||
        #define portGET_CORE_ID()    xPortGET_CORE_ID()
 | 
			
		||||
        #define coreid    xPortGET_CORE_ID()
 | 
			
		||||
 | 
			
		||||
/* Request the core ID x to yield. */
 | 
			
		||||
        extern void vPortYieldCore( unsigned int coreID );
 | 
			
		||||
 | 
			
		||||
        #define portYIELD_CORE( x )                vPortYieldCore( x )
 | 
			
		||||
 | 
			
		||||
        #define portENTER_CRITICAL_FROM_ISR()      vTaskEnterCriticalFromISR()
 | 
			
		||||
        #define portEXIT_CRITICAL_FROM_ISR( x )    vTaskExitCriticalFromISR( x )
 | 
			
		||||
 | 
			
		||||
    #endif /* if ( configNUMBER_OF_CORES > 1 ) */
 | 
			
		||||
 | 
			
		||||
    #if ( configNUMBER_OF_CORES == 1 )
 | 
			
		||||
        #define portGET_ISR_LOCK()
 | 
			
		||||
        #define portRELEASE_ISR_LOCK()
 | 
			
		||||
        #define portGET_TASK_LOCK()
 | 
			
		||||
        #define portRELEASE_TASK_LOCK()
 | 
			
		||||
    #else
 | 
			
		||||
        extern void vPortRecursiveLockAcquire( BaseType_t xFromIsr );
 | 
			
		||||
        extern void vPortRecursiveLockRelease( BaseType_t xFromIsr );
 | 
			
		||||
 | 
			
		||||
        #define portGET_ISR_LOCK()         vPortRecursiveLockAcquire( pdTRUE )
 | 
			
		||||
        #define portRELEASE_ISR_LOCK()     vPortRecursiveLockRelease( pdTRUE )
 | 
			
		||||
        #define portGET_TASK_LOCK()        vPortRecursiveLockAcquire( pdFALSE )
 | 
			
		||||
        #define portRELEASE_TASK_LOCK()    vPortRecursiveLockRelease( pdFALSE )
 | 
			
		||||
    #endif /* if ( configNUMBER_OF_CORES == 1 ) */
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
/* Critical section management. */
 | 
			
		||||
 | 
			
		||||
/* The critical nesting functions defined within tasks.c */
 | 
			
		||||
 | 
			
		||||
    extern void vTaskEnterCritical( void );
 | 
			
		||||
    extern void vTaskExitCritical( void );
 | 
			
		||||
 | 
			
		||||
/* Macro to mark the start of a critical code region */
 | 
			
		||||
    #define portENTER_CRITICAL()    vTaskEnterCritical()
 | 
			
		||||
 | 
			
		||||
/* Macro to mark the end of a critical code region */
 | 
			
		||||
    #define portEXIT_CRITICAL()     vTaskExitCritical()
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
/* Macros to set and clear the interrupt mask. */
 | 
			
		||||
    portLONG xPortSetInterruptMask();
 | 
			
		||||
    void vPortClearInterruptMask( portLONG );
 | 
			
		||||
 | 
			
		||||
    #define portSET_INTERRUPT_MASK()                  xPortSetInterruptMask()
 | 
			
		||||
    #define portCLEAR_INTERRUPT_MASK( x )             vPortClearInterruptMask( ( x ) )
 | 
			
		||||
    #define portSET_INTERRUPT_MASK_FROM_ISR()         xPortSetInterruptMask()
 | 
			
		||||
    #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x )    vPortClearInterruptMask( ( x ) )
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
 | 
			
		||||
 | 
			
		||||
    #define portTASK_FUNCTION_PROTO( vFunction, pvParameters )    void vFunction( void * pvParameters )
 | 
			
		||||
    #define portTASK_FUNCTION( vFunction, pvParameters )          void vFunction( void * pvParameters )
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    #ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
    #endif
 | 
			
		||||
#endif /* PORTMACRO_H */
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user