123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- /*
- * FreeRTOS Kernel V10.4.6
- * 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
- *
- */
- /*
- Changes from V3.0.0
- Changes from V3.0.1
- */
- #ifndef PORTMACRO_H
- #define PORTMACRO_H
- #if !defined(_SERIES) || _SERIES != 18
- #error "WizC supports FreeRTOS on the Microchip PIC18-series only"
- #endif
- #if !defined(QUICKCALL) || QUICKCALL != 1
- #error "QuickCall must be enabled (see ProjectOptions/Optimisations)"
- #endif
- #include <stddef.h>
- #include <pic.h>
- #define portCHAR char
- #define portFLOAT float
- #define portDOUBLE portFLOAT
- #define portLONG long
- #define portSHORT short
- #define portSTACK_TYPE uint8_t
- #define portBASE_TYPE char
- typedef portSTACK_TYPE StackType_t;
- typedef signed char BaseType_t;
- typedef unsigned char UBaseType_t;
- #if( configUSE_16_BIT_TICKS == 1 )
- typedef uint16_t TickType_t;
- #define portMAX_DELAY ( TickType_t ) ( 0xFFFF )
- #else
- typedef uint32_t TickType_t;
- #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF )
- #endif
- #define portBYTE_ALIGNMENT 1
- /*-----------------------------------------------------------*/
- /*
- * Constant used for context switch macro when we require the interrupt
- * enable state to be forced when the interrupted task is switched back in.
- */
- #define portINTERRUPTS_FORCED (0x01)
- /*
- * Constant used for context switch macro when we require the interrupt
- * enable state to be unchanged when the interrupted task is switched back in.
- */
- #define portINTERRUPTS_UNCHANGED (0x00)
- /* Initial interrupt enable state for newly created tasks. This value is
- * used when a task switches in for the first time.
- */
- #define portINTERRUPTS_INITIAL_STATE (portINTERRUPTS_FORCED)
- /*
- * Macros to modify the global interrupt enable bit in INTCON.
- */
- #define portDISABLE_INTERRUPTS() \
- do \
- { \
- bGIE=0; \
- } while(bGIE) // MicroChip recommends this check!
- #define portENABLE_INTERRUPTS() \
- do \
- { \
- bGIE=1; \
- } while(0)
- /*-----------------------------------------------------------*/
- /*
- * Critical section macros.
- */
- extern uint8_t ucCriticalNesting;
- #define portNO_CRITICAL_SECTION_NESTING ( ( uint8_t ) 0 )
- #define portENTER_CRITICAL() \
- do \
- { \
- portDISABLE_INTERRUPTS(); \
- \
- /* \
- * Now interrupts are disabled ucCriticalNesting \
- * can be accessed directly. Increment \
- * ucCriticalNesting to keep a count of how \
- * many times portENTER_CRITICAL() has been called. \
- */ \
- ucCriticalNesting++; \
- } while(0)
- #define portEXIT_CRITICAL() \
- do \
- { \
- if(ucCriticalNesting > portNO_CRITICAL_SECTION_NESTING) \
- { \
- /* \
- * Decrement the nesting count as we are leaving a \
- * critical section. \
- */ \
- ucCriticalNesting--; \
- } \
- \
- /* \
- * If the nesting level has reached zero then \
- * interrupts should be re-enabled. \
- */ \
- if( ucCriticalNesting == portNO_CRITICAL_SECTION_NESTING ) \
- { \
- portENABLE_INTERRUPTS(); \
- } \
- } while(0)
- /*-----------------------------------------------------------*/
- /*
- * The minimal stacksize is calculated on the first reference of
- * portMINIMAL_STACK_SIZE. Some input to this calculation is
- * compiletime determined, other input is port-defined (see port.c)
- */
- extern uint16_t usPortCALCULATE_MINIMAL_STACK_SIZE( void );
- extern uint16_t usCalcMinStackSize;
- #define portMINIMAL_STACK_SIZE \
- ((usCalcMinStackSize == 0) \
- ? usPortCALCULATE_MINIMAL_STACK_SIZE() \
- : usCalcMinStackSize )
- /*
- * WizC uses a downgrowing stack
- */
- #define portSTACK_GROWTH ( -1 )
- /*-----------------------------------------------------------*/
- /*
- * Macro's that pushes all the registers that make up the context of a task onto
- * the stack, then saves the new top of stack into the TCB. TOSU and TBLPTRU
- * are only saved/restored on devices with more than 64kB (32k Words) ROM.
- *
- * The stackpointer is helt by WizC in FSR2 and points to the first free byte.
- * WizC uses a "downgrowing" stack. There is no framepointer.
- *
- * We keep track of the interruptstatus using ucCriticalNesting. When this
- * value equals zero, interrupts have to be enabled upon exit from the
- * portRESTORE_CONTEXT macro.
- *
- * If this is called from an ISR then the interrupt enable bits must have been
- * set for the ISR to ever get called. Therefore we want to save
- * ucCriticalNesting with value zero. This means the interrupts will again be
- * re-enabled when the interrupted task is switched back in.
- *
- * If this is called from a manual context switch (i.e. from a call to yield),
- * then we want to keep the current value of ucCritialNesting so it is restored
- * with its current value. This allows a yield from within a critical section.
- *
- * The compiler uses some locations at the bottom of RAM for temporary
- * storage. The compiler may also have been instructed to optimize
- * function-parameters and local variables to global storage. The compiler
- * uses an area called LocOpt for this wizC feature.
- * The total overheadstorage has to be saved in it's entirety as part of
- * a task context. These macro's store/restore from data address 0x0000 to
- * (OVERHEADPAGE0-LOCOPTSIZE+MAXLOCOPTSIZE - 1).
- * OVERHEADPAGE0, LOCOPTSIZE and MAXLOCOPTSIZE are compiler-generated
- * assembler definitions.
- */
- #define portSAVE_CONTEXT( ucInterruptForced ) \
- do \
- { \
- portDISABLE_INTERRUPTS(); \
- \
- _Pragma("asm") \
- ; \
- ; Push the relevant SFR's onto the task's stack \
- ; \
- movff STATUS,POSTDEC2 \
- movff WREG,POSTDEC2 \
- movff BSR,POSTDEC2 \
- movff PRODH,POSTDEC2 \
- movff PRODL,POSTDEC2 \
- movff FSR0H,POSTDEC2 \
- movff FSR0L,POSTDEC2 \
- movff FSR1H,POSTDEC2 \
- movff FSR1L,POSTDEC2 \
- movff TABLAT,POSTDEC2 \
- if __ROMSIZE > 0x8000 \
- movff TBLPTRU,POSTDEC2 \
- endif \
- movff TBLPTRH,POSTDEC2 \
- movff TBLPTRL,POSTDEC2 \
- if __ROMSIZE > 0x8000 \
- movff PCLATU,POSTDEC2 \
- endif \
- movff PCLATH,POSTDEC2 \
- ; \
- ; Store the compiler-scratch-area as described above. \
- ; \
- movlw OVERHEADPAGE0-LOCOPTSIZE+MAXLOCOPTSIZE \
- clrf FSR0L,ACCESS \
- clrf FSR0H,ACCESS \
- _rtos_S1: \
- movff POSTINC0,POSTDEC2 \
- decfsz WREG,W,ACCESS \
- SMARTJUMP _rtos_S1 \
- ; \
- ; Save the pic call/return-stack belonging to the \
- ; current task by copying it to the task's software- \
- ; stack. We save the hardware stack pointer (which \
- ; is the number of addresses on the stack) in the \
- ; W-register first because we need it later and it \
- ; is modified in the save-loop by executing pop's. \
- ; After the loop the W-register is stored on the \
- ; stack, too. \
- ; \
- movf STKPTR,W,ACCESS \
- bz _rtos_s3 \
- _rtos_S2: \
- if __ROMSIZE > 0x8000 \
- movff TOSU,POSTDEC2 \
- endif \
- movff TOSH,POSTDEC2 \
- movff TOSL,POSTDEC2 \
- pop \
- tstfsz STKPTR,ACCESS \
- SMARTJUMP _rtos_S2 \
- _rtos_s3: \
- movwf POSTDEC2,ACCESS \
- ; \
- ; Next the value for ucCriticalNesting used by the \
- ; task is stored on the stack. When \
- ; (ucInterruptForced == portINTERRUPTS_FORCED), we save \
- ; it as 0 (portNO_CRITICAL_SECTION_NESTING). \
- ; \
- if ucInterruptForced == portINTERRUPTS_FORCED \
- clrf POSTDEC2,ACCESS \
- else \
- movff ucCriticalNesting,POSTDEC2 \
- endif \
- ; \
- ; Save the new top of the software stack in the TCB. \
- ; \
- movff pxCurrentTCB,FSR0L \
- movff pxCurrentTCB+1,FSR0H \
- movff FSR2L,POSTINC0 \
- movff FSR2H,POSTINC0 \
- _Pragma("asmend") \
- } while(0)
- /************************************************************/
- /*
- * This is the reverse of portSAVE_CONTEXT.
- */
- #define portRESTORE_CONTEXT() \
- do \
- { \
- _Pragma("asm") \
- ; \
- ; Set FSR0 to point to pxCurrentTCB->pxTopOfStack. \
- ; \
- movff pxCurrentTCB,FSR0L \
- movff pxCurrentTCB+1,FSR0H \
- ; \
- ; De-reference FSR0 to set the address it holds into \
- ; FSR2 (i.e. *( pxCurrentTCB->pxTopOfStack ) ). FSR2 \
- ; is used by wizC as stackpointer. \
- ; \
- movff POSTINC0,FSR2L \
- movff POSTINC0,FSR2H \
- ; \
- ; Next, the value for ucCriticalNesting used by the \
- ; task is retrieved from the stack. \
- ; \
- movff PREINC2,ucCriticalNesting \
- ; \
- ; Rebuild the pic call/return-stack. The number of \
- ; return addresses is the next item on the task stack. \
- ; Save this number in PRODL. Then fetch the addresses \
- ; and store them on the hardwarestack. \
- ; The datasheets say we can't use movff here... \
- ; \
- movff PREINC2,PRODL // Use PRODL as tempregister \
- clrf STKPTR,ACCESS \
- _rtos_R1: \
- push \
- movf PREINC2,W,ACCESS \
- movwf TOSL,ACCESS \
- movf PREINC2,W,ACCESS \
- movwf TOSH,ACCESS \
- if __ROMSIZE > 0x8000 \
- movf PREINC2,W,ACCESS \
- movwf TOSU,ACCESS \
- else \
- clrf TOSU,ACCESS \
- endif \
- decfsz PRODL,F,ACCESS \
- SMARTJUMP _rtos_R1 \
- ; \
- ; Restore the compiler's working storage area to page 0 \
- ; \
- movlw OVERHEADPAGE0-LOCOPTSIZE+MAXLOCOPTSIZE \
- movwf FSR0L,ACCESS \
- clrf FSR0H,ACCESS \
- _rtos_R2: \
- decf FSR0L,F,ACCESS \
- movff PREINC2,INDF0 \
- tstfsz FSR0L,ACCESS \
- SMARTJUMP _rtos_R2 \
- ; \
- ; Restore the sfr's forming the tasks context. \
- ; We cannot yet restore bsr, w and status because \
- ; we need these registers for a final test. \
- ; \
- movff PREINC2,PCLATH \
- if __ROMSIZE > 0x8000 \
- movff PREINC2,PCLATU \
- else \
- clrf PCLATU,ACCESS \
- endif \
- movff PREINC2,TBLPTRL \
- movff PREINC2,TBLPTRH \
- if __ROMSIZE > 0x8000 \
- movff PREINC2,TBLPTRU \
- else \
- clrf TBLPTRU,ACCESS \
- endif \
- movff PREINC2,TABLAT \
- movff PREINC2,FSR1L \
- movff PREINC2,FSR1H \
- movff PREINC2,FSR0L \
- movff PREINC2,FSR0H \
- movff PREINC2,PRODL \
- movff PREINC2,PRODH \
- ; \
- ; The return from portRESTORE_CONTEXT() depends on \
- ; the value of ucCriticalNesting. When it is zero, \
- ; interrupts need to be enabled. This is done via a \
- ; retfie instruction because we need the \
- ; interrupt-enabling and the return to the restored \
- ; task to be uninterruptable. \
- ; Because bsr, status and W are affected by the test \
- ; they are restored after the test. \
- ; \
- movlb ucCriticalNesting>>8 \
- tstfsz ucCriticalNesting,BANKED \
- SMARTJUMP _rtos_R4 \
- _rtos_R3: \
- movff PREINC2,BSR \
- movff PREINC2,WREG \
- movff PREINC2,STATUS \
- retfie 0 ; Return enabling interrupts \
- _rtos_R4: \
- movff PREINC2,BSR \
- movff PREINC2,WREG \
- movff PREINC2,STATUS \
- return 0 ; Return without affecting interrupts \
- _Pragma("asmend") \
- } while(0)
- /*-----------------------------------------------------------*/
- #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
- /*-----------------------------------------------------------*/
- extern void vPortYield( void );
- #define portYIELD() vPortYield()
- #define portNOP() _Pragma("asm") \
- nop \
- _Pragma("asmend")
- /*-----------------------------------------------------------*/
- #define portTASK_FUNCTION( xFunction, pvParameters ) \
- void pointed xFunction( void *pvParameters ) \
- _Pragma(asmfunc xFunction)
- #define portTASK_FUNCTION_PROTO portTASK_FUNCTION
- /*-----------------------------------------------------------*/
- #define volatile
- #define register
- #endif /* PORTMACRO_H */
|