mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 13:01:57 -04:00
CI-CD Updates (#768)
* Use new version of CI-CD Actions * Use cSpell spell check, and use ubuntu-20.04 for formatting check * Format and spell check all files in the portable directory * Remove the https:// from #errors and #warnings as uncrustify attempts to change it to /* * Use checkout@v3 instead of checkout@v2 on all jobs ---------
This commit is contained in:
parent
d6bccb1f4c
commit
5fb9b50da8
918
.github/.cSpellWords.txt
vendored
Normal file
918
.github/.cSpellWords.txt
vendored
Normal file
|
@ -0,0 +1,918 @@
|
||||||
|
AASR
|
||||||
|
ABETRG
|
||||||
|
ABSR
|
||||||
|
ABTSZ
|
||||||
|
ACCAH
|
||||||
|
ACCAL
|
||||||
|
ACCAU
|
||||||
|
ACCBH
|
||||||
|
ACCBL
|
||||||
|
ACCBU
|
||||||
|
ACLK
|
||||||
|
acpa
|
||||||
|
ACPA
|
||||||
|
acpc
|
||||||
|
ACPC
|
||||||
|
addi
|
||||||
|
addiu
|
||||||
|
ADTRG
|
||||||
|
aeevt
|
||||||
|
AEEVT
|
||||||
|
AERR
|
||||||
|
AIRCR
|
||||||
|
ALMIEN
|
||||||
|
ALMV
|
||||||
|
ANDC
|
||||||
|
ANDCCR
|
||||||
|
APIC
|
||||||
|
APROCFREQ
|
||||||
|
APSR
|
||||||
|
ARMCM
|
||||||
|
Armv
|
||||||
|
ARMVFP
|
||||||
|
ASTRINGZ
|
||||||
|
aswtrg
|
||||||
|
ASWTRG
|
||||||
|
Ateml
|
||||||
|
ATMEGA
|
||||||
|
Atmel
|
||||||
|
ATMEL
|
||||||
|
atomatic
|
||||||
|
ATPASTE
|
||||||
|
AVRDX
|
||||||
|
BANDL
|
||||||
|
bcpb
|
||||||
|
BCPB
|
||||||
|
bcpc
|
||||||
|
BCPC
|
||||||
|
beevt
|
||||||
|
BEEVT
|
||||||
|
BERR
|
||||||
|
bfextu
|
||||||
|
Biagioni
|
||||||
|
bics
|
||||||
|
BISR
|
||||||
|
BODIEN
|
||||||
|
BODSTS
|
||||||
|
BRGR
|
||||||
|
brhi
|
||||||
|
brne
|
||||||
|
bswtrg
|
||||||
|
BSWTRG
|
||||||
|
CANEN
|
||||||
|
CANRX
|
||||||
|
CANTX
|
||||||
|
capitalisation
|
||||||
|
cbmc
|
||||||
|
CBMC
|
||||||
|
cbor
|
||||||
|
CBOR
|
||||||
|
CCIE
|
||||||
|
CCMP
|
||||||
|
CCNT
|
||||||
|
CCNTR
|
||||||
|
CCPN
|
||||||
|
CCPR
|
||||||
|
CDTY
|
||||||
|
CDTYR
|
||||||
|
CFBS
|
||||||
|
CFRC
|
||||||
|
CHDIV
|
||||||
|
CHDR
|
||||||
|
CHRL
|
||||||
|
CHSR
|
||||||
|
CICR
|
||||||
|
CISR
|
||||||
|
CKDIV
|
||||||
|
CKEY
|
||||||
|
CKGR
|
||||||
|
CKLO
|
||||||
|
CKPS
|
||||||
|
CLDIV
|
||||||
|
CLKA
|
||||||
|
CLKB
|
||||||
|
CLKEN
|
||||||
|
clki
|
||||||
|
CLKI
|
||||||
|
CLKP
|
||||||
|
CLKS
|
||||||
|
CLKSTA
|
||||||
|
CLRB
|
||||||
|
CLRF
|
||||||
|
CLRPSW
|
||||||
|
CMCNT
|
||||||
|
CMCON
|
||||||
|
CMCOR
|
||||||
|
CMCR
|
||||||
|
CMIE
|
||||||
|
cmock
|
||||||
|
Cmock
|
||||||
|
CMock
|
||||||
|
CMOCK
|
||||||
|
cmpx
|
||||||
|
CMSIS
|
||||||
|
CMSTR
|
||||||
|
CNTE
|
||||||
|
coalescences
|
||||||
|
CODAN
|
||||||
|
codecov
|
||||||
|
CODR
|
||||||
|
comms
|
||||||
|
COMPA
|
||||||
|
CONFG
|
||||||
|
CORTUS
|
||||||
|
coverity
|
||||||
|
Coverity
|
||||||
|
covfs
|
||||||
|
COVFS
|
||||||
|
CPACR
|
||||||
|
cpas
|
||||||
|
CPAS
|
||||||
|
cpbs
|
||||||
|
CPBS
|
||||||
|
cpcdis
|
||||||
|
CPCDIS
|
||||||
|
CPCS
|
||||||
|
cpcstop
|
||||||
|
CPCSTOP
|
||||||
|
CPCTRG
|
||||||
|
CPIV
|
||||||
|
CPRD
|
||||||
|
CPRDR
|
||||||
|
CPRE
|
||||||
|
cpsid
|
||||||
|
cpsie
|
||||||
|
CPSR
|
||||||
|
CPUID
|
||||||
|
CRCB
|
||||||
|
crflash
|
||||||
|
CRGFLG
|
||||||
|
CRGINT
|
||||||
|
crhook
|
||||||
|
croutine
|
||||||
|
CRTV
|
||||||
|
CSAAT
|
||||||
|
csrr
|
||||||
|
csrs
|
||||||
|
csrw
|
||||||
|
CTCR
|
||||||
|
ctest
|
||||||
|
CTRLA
|
||||||
|
CTSIC
|
||||||
|
CUPD
|
||||||
|
CUPDR
|
||||||
|
CWGR
|
||||||
|
cxsf
|
||||||
|
CYGNAL
|
||||||
|
DADR
|
||||||
|
daif
|
||||||
|
DAIFCLR
|
||||||
|
DAIFSET
|
||||||
|
DATAR
|
||||||
|
DATAW
|
||||||
|
DATNB
|
||||||
|
DATRDY
|
||||||
|
DBGU
|
||||||
|
DCDIC
|
||||||
|
DCMR
|
||||||
|
DCOUNT
|
||||||
|
decf
|
||||||
|
decfsz
|
||||||
|
DECNT
|
||||||
|
DFPU
|
||||||
|
DFREERTOS
|
||||||
|
dicr
|
||||||
|
DICR
|
||||||
|
DIVB
|
||||||
|
DLYBCS
|
||||||
|
DLYBCT
|
||||||
|
DLYBS
|
||||||
|
DLYI
|
||||||
|
DNDEBUG
|
||||||
|
DOCOUNT
|
||||||
|
DOENDH
|
||||||
|
DOENDL
|
||||||
|
DOHIGH
|
||||||
|
DOLOW
|
||||||
|
DOSTARTH
|
||||||
|
DOSTARTL
|
||||||
|
DPFPU
|
||||||
|
DPLB
|
||||||
|
DPOPM
|
||||||
|
DPSW
|
||||||
|
DPUSHM
|
||||||
|
DRDY
|
||||||
|
DRFCS
|
||||||
|
DRPT
|
||||||
|
DRXD
|
||||||
|
DSLPE
|
||||||
|
DSNACK
|
||||||
|
DSPIC
|
||||||
|
DSRIC
|
||||||
|
DSWPAG
|
||||||
|
DTGLE
|
||||||
|
DTREN
|
||||||
|
DTXD
|
||||||
|
DUNITY
|
||||||
|
DVAR
|
||||||
|
EABI
|
||||||
|
ecall
|
||||||
|
ECIT
|
||||||
|
ECRS
|
||||||
|
ECRSDV
|
||||||
|
eevt
|
||||||
|
EEVT
|
||||||
|
eevtedg
|
||||||
|
EEVTEDG
|
||||||
|
EFRHD
|
||||||
|
EINT
|
||||||
|
EIPC
|
||||||
|
EIPSW
|
||||||
|
Elektronika
|
||||||
|
EMACB
|
||||||
|
EMDC
|
||||||
|
EMDIO
|
||||||
|
emption
|
||||||
|
endm
|
||||||
|
ENDRX
|
||||||
|
ENDTX
|
||||||
|
enetrg
|
||||||
|
ENETRG
|
||||||
|
ENMFILE
|
||||||
|
EOICR
|
||||||
|
epage
|
||||||
|
EPEDS
|
||||||
|
EPINT
|
||||||
|
EPTYPE
|
||||||
|
EQIC
|
||||||
|
EQIF
|
||||||
|
EQMK
|
||||||
|
EREFCK
|
||||||
|
eret
|
||||||
|
ERRA
|
||||||
|
ERSTL
|
||||||
|
ERXCK
|
||||||
|
ERXDV
|
||||||
|
ERXER
|
||||||
|
Espeche
|
||||||
|
Espressif
|
||||||
|
ESTATUS
|
||||||
|
ETRCS
|
||||||
|
ETRGEDG
|
||||||
|
etrgs
|
||||||
|
ETRGS
|
||||||
|
ETXCK
|
||||||
|
ETXEN
|
||||||
|
ETXER
|
||||||
|
evba
|
||||||
|
EVBA
|
||||||
|
EWARM
|
||||||
|
EWAVR
|
||||||
|
EWRL
|
||||||
|
EWRX
|
||||||
|
EXID
|
||||||
|
expandnl
|
||||||
|
EXTRSM
|
||||||
|
FADD
|
||||||
|
FCMD
|
||||||
|
fcolor
|
||||||
|
FCSE
|
||||||
|
fdiagnostics
|
||||||
|
fdiv
|
||||||
|
FDIV
|
||||||
|
FEDPICC
|
||||||
|
FERR
|
||||||
|
FFDR
|
||||||
|
FFER
|
||||||
|
FFSR
|
||||||
|
FIDI
|
||||||
|
FLASH
|
||||||
|
Flsh
|
||||||
|
FLSH
|
||||||
|
FMCN
|
||||||
|
FMRXNE
|
||||||
|
FMXR
|
||||||
|
fninit
|
||||||
|
fnsave
|
||||||
|
FNTR
|
||||||
|
FOSC
|
||||||
|
FPCCR
|
||||||
|
FPCSR
|
||||||
|
FPSW
|
||||||
|
FPUL
|
||||||
|
FRDY
|
||||||
|
Frieder
|
||||||
|
FSDEN
|
||||||
|
FSEDGE
|
||||||
|
FSLEN
|
||||||
|
FSOS
|
||||||
|
FSR
|
||||||
|
fwait
|
||||||
|
GCACC
|
||||||
|
GCTRL
|
||||||
|
getvect
|
||||||
|
GIEH
|
||||||
|
GIEL
|
||||||
|
GIRQ
|
||||||
|
GLBSTATE
|
||||||
|
GMSK
|
||||||
|
GNURX
|
||||||
|
GOVRE
|
||||||
|
gpio
|
||||||
|
GPIO
|
||||||
|
GPNVM
|
||||||
|
GPTA
|
||||||
|
HCLK
|
||||||
|
Hitach
|
||||||
|
HRESP
|
||||||
|
HWHSH
|
||||||
|
HWORD
|
||||||
|
HWRD
|
||||||
|
IADR
|
||||||
|
IADRSZ
|
||||||
|
ICCAVR
|
||||||
|
ICCBPR
|
||||||
|
ICCEOIR
|
||||||
|
ICCIAR
|
||||||
|
ICCICAR
|
||||||
|
ICCPMR
|
||||||
|
ICCR
|
||||||
|
ICCRPR
|
||||||
|
ICCRX
|
||||||
|
ICERST
|
||||||
|
ICSR
|
||||||
|
IDCR
|
||||||
|
IECR
|
||||||
|
IFDR
|
||||||
|
IFER
|
||||||
|
IFLASH
|
||||||
|
IFSR
|
||||||
|
imajeff
|
||||||
|
INACK
|
||||||
|
INDF
|
||||||
|
inpw
|
||||||
|
INTE
|
||||||
|
INTFRCH
|
||||||
|
INTFRCL
|
||||||
|
INTIT
|
||||||
|
INTTM
|
||||||
|
IODEFINE
|
||||||
|
IORLW
|
||||||
|
IPEN
|
||||||
|
IPLB
|
||||||
|
ipsr
|
||||||
|
IPSR
|
||||||
|
iret
|
||||||
|
IRET
|
||||||
|
IRXFCS
|
||||||
|
ISRAM
|
||||||
|
ISRR
|
||||||
|
ISR's
|
||||||
|
ISRS
|
||||||
|
ISRTICK
|
||||||
|
ITIF
|
||||||
|
ITMC
|
||||||
|
ITMK
|
||||||
|
ittt
|
||||||
|
JFRAME
|
||||||
|
JTAG
|
||||||
|
JTVIC
|
||||||
|
Kamil
|
||||||
|
kbhit
|
||||||
|
Kbyte
|
||||||
|
Krutmann
|
||||||
|
LAPIC
|
||||||
|
LCDR
|
||||||
|
LCOL
|
||||||
|
lcov
|
||||||
|
ldaa
|
||||||
|
LDATA
|
||||||
|
LDBDIS
|
||||||
|
LDBSTOP
|
||||||
|
ldmdb
|
||||||
|
LDMFD
|
||||||
|
ldmia
|
||||||
|
LDRA
|
||||||
|
ldras
|
||||||
|
LDRAS
|
||||||
|
ldrb
|
||||||
|
ldrbs
|
||||||
|
LDRBS
|
||||||
|
LDRNE
|
||||||
|
ldsr
|
||||||
|
lidt
|
||||||
|
LINKR
|
||||||
|
LJMP
|
||||||
|
LLIO
|
||||||
|
lovrs
|
||||||
|
LOVRS
|
||||||
|
lpcount
|
||||||
|
lpend
|
||||||
|
lpstart
|
||||||
|
LPTHREAD
|
||||||
|
lsls
|
||||||
|
LSPEN
|
||||||
|
LSPENS
|
||||||
|
ltorg
|
||||||
|
LWRD
|
||||||
|
MABT
|
||||||
|
MACL
|
||||||
|
MAINF
|
||||||
|
MAINRDY
|
||||||
|
MAIR
|
||||||
|
Mang
|
||||||
|
Mbits
|
||||||
|
mcause
|
||||||
|
MCFR
|
||||||
|
MCKA
|
||||||
|
MCKB
|
||||||
|
MCKR
|
||||||
|
MCKRDY
|
||||||
|
MCLK
|
||||||
|
MCU
|
||||||
|
MDDR
|
||||||
|
MDER
|
||||||
|
MDIO
|
||||||
|
MDLC
|
||||||
|
MDSR
|
||||||
|
mepc
|
||||||
|
mevents
|
||||||
|
MFCR
|
||||||
|
mfear
|
||||||
|
mfedr
|
||||||
|
mfesr
|
||||||
|
mffsr
|
||||||
|
mfgpr
|
||||||
|
mfhi
|
||||||
|
MFID
|
||||||
|
mflo
|
||||||
|
mfloat
|
||||||
|
mfmsr
|
||||||
|
mfpu
|
||||||
|
mhartid
|
||||||
|
MIDE
|
||||||
|
Mikro
|
||||||
|
MIKROC
|
||||||
|
misra
|
||||||
|
Misra
|
||||||
|
MISRA
|
||||||
|
MMCR
|
||||||
|
MMSYSERR
|
||||||
|
MOSC
|
||||||
|
MOSCS
|
||||||
|
MOSI
|
||||||
|
movem
|
||||||
|
moveq
|
||||||
|
MOVF
|
||||||
|
MOVFF
|
||||||
|
movhi
|
||||||
|
movia
|
||||||
|
movlb
|
||||||
|
movlw
|
||||||
|
movne
|
||||||
|
movs
|
||||||
|
movw
|
||||||
|
MOVWF
|
||||||
|
movx
|
||||||
|
MPLAB
|
||||||
|
MPUCTRL
|
||||||
|
MQTT
|
||||||
|
MRDY
|
||||||
|
MREAD
|
||||||
|
mret
|
||||||
|
mrseq
|
||||||
|
mrsne
|
||||||
|
MRTR
|
||||||
|
MSBF
|
||||||
|
MSDIS
|
||||||
|
MSEN
|
||||||
|
mspgcc
|
||||||
|
msreq
|
||||||
|
mstatus
|
||||||
|
MSTATUS
|
||||||
|
MSTP
|
||||||
|
MSTPA
|
||||||
|
MSTPCR
|
||||||
|
MSTPCRA
|
||||||
|
MSTPCRC
|
||||||
|
MSTR
|
||||||
|
MTCR
|
||||||
|
mthi
|
||||||
|
MTIOA
|
||||||
|
MTIOB
|
||||||
|
mtlo
|
||||||
|
mtsr
|
||||||
|
MVFACGU
|
||||||
|
MVFACHI
|
||||||
|
MVFACLO
|
||||||
|
MVFACMI
|
||||||
|
MVFC
|
||||||
|
MVTACGU
|
||||||
|
MVTACHI
|
||||||
|
MVTACLO
|
||||||
|
MVTC
|
||||||
|
MVTIPL
|
||||||
|
NCFGR
|
||||||
|
NCPHA
|
||||||
|
NEBP
|
||||||
|
NFIQ
|
||||||
|
Nios
|
||||||
|
NIOSII
|
||||||
|
NIRQ
|
||||||
|
NOGIC
|
||||||
|
noheap
|
||||||
|
nostdint
|
||||||
|
NPCS
|
||||||
|
NRSTL
|
||||||
|
NSACR
|
||||||
|
NSFPU
|
||||||
|
NSSR
|
||||||
|
NTRST
|
||||||
|
NVIC
|
||||||
|
ODAT
|
||||||
|
ODSR
|
||||||
|
OPMOD
|
||||||
|
optimisations
|
||||||
|
OPTIMISED
|
||||||
|
optimiser
|
||||||
|
ORCCR
|
||||||
|
orrs
|
||||||
|
OSCBYPASS
|
||||||
|
OSCEN
|
||||||
|
OSCOFF
|
||||||
|
OSCOUNT
|
||||||
|
OSMC
|
||||||
|
outpw
|
||||||
|
OVLY
|
||||||
|
OVRE
|
||||||
|
OVRES
|
||||||
|
OVRUN
|
||||||
|
OWATCOM
|
||||||
|
OWDR
|
||||||
|
OWER
|
||||||
|
OWSR
|
||||||
|
PAGEN
|
||||||
|
PCDR
|
||||||
|
PCER
|
||||||
|
PCKR
|
||||||
|
PCLATH
|
||||||
|
PCLATU
|
||||||
|
PCLK
|
||||||
|
PCLKSEL
|
||||||
|
PCSR
|
||||||
|
PCXI
|
||||||
|
PDSR
|
||||||
|
PEIE
|
||||||
|
PENDSV
|
||||||
|
PENDSVCLEAR
|
||||||
|
PENDSVSET
|
||||||
|
PENSVCLEAR
|
||||||
|
PERIODH
|
||||||
|
PERIODL
|
||||||
|
periph
|
||||||
|
PERIPH
|
||||||
|
PFRE
|
||||||
|
phelter
|
||||||
|
PHYA
|
||||||
|
PICNT
|
||||||
|
pico
|
||||||
|
picolibc
|
||||||
|
Picolibc
|
||||||
|
PICOLIBC
|
||||||
|
PIEN
|
||||||
|
PIIR
|
||||||
|
PIMR
|
||||||
|
PIOA
|
||||||
|
PIOB
|
||||||
|
PISR
|
||||||
|
PITC
|
||||||
|
PITEN
|
||||||
|
PITIEN
|
||||||
|
PIVR
|
||||||
|
PLLB
|
||||||
|
PLLR
|
||||||
|
popa
|
||||||
|
popm
|
||||||
|
POPNE
|
||||||
|
POPW
|
||||||
|
popx
|
||||||
|
portcomn
|
||||||
|
PORTEN
|
||||||
|
portex
|
||||||
|
portisr
|
||||||
|
POWERUP
|
||||||
|
ppuc
|
||||||
|
PPUDR
|
||||||
|
PPUER
|
||||||
|
PPUSR
|
||||||
|
ppux
|
||||||
|
PRCR
|
||||||
|
PREA
|
||||||
|
PREB
|
||||||
|
PRIA
|
||||||
|
Prioritised
|
||||||
|
PRIS
|
||||||
|
PROCDLY
|
||||||
|
PRODH
|
||||||
|
PRODL
|
||||||
|
PROGE
|
||||||
|
Prokic
|
||||||
|
prtmacro
|
||||||
|
psha
|
||||||
|
psplim
|
||||||
|
PSPLIM
|
||||||
|
PSTDBY
|
||||||
|
PSVPAG
|
||||||
|
PTCR
|
||||||
|
PTSR
|
||||||
|
Pulpino
|
||||||
|
PUON
|
||||||
|
pusha
|
||||||
|
pushf
|
||||||
|
pushm
|
||||||
|
PUSHNE
|
||||||
|
PUSHW
|
||||||
|
pushx
|
||||||
|
PWMC
|
||||||
|
RAMPZ
|
||||||
|
RASR
|
||||||
|
Rationalised
|
||||||
|
Raynald
|
||||||
|
RBAR
|
||||||
|
RBOF
|
||||||
|
RBQP
|
||||||
|
RBSY
|
||||||
|
RCALL
|
||||||
|
RCAP
|
||||||
|
RCIF
|
||||||
|
RCMR
|
||||||
|
RCOMP
|
||||||
|
RCOUNT
|
||||||
|
rddsp
|
||||||
|
RDRF
|
||||||
|
reent
|
||||||
|
REENT
|
||||||
|
REGA
|
||||||
|
RELD
|
||||||
|
Renesas
|
||||||
|
reta
|
||||||
|
reti
|
||||||
|
RETP
|
||||||
|
RETTO
|
||||||
|
RFEIA
|
||||||
|
RFMR
|
||||||
|
RIIC
|
||||||
|
RIPL
|
||||||
|
riscv
|
||||||
|
RLAR
|
||||||
|
RLCE
|
||||||
|
RLES
|
||||||
|
RLEX
|
||||||
|
RMII
|
||||||
|
RMWUPE
|
||||||
|
RNCR
|
||||||
|
RNPR
|
||||||
|
ROUSSET
|
||||||
|
ROVR
|
||||||
|
RSHR
|
||||||
|
rslcx
|
||||||
|
RSLCX
|
||||||
|
RSMINPR
|
||||||
|
RSTC
|
||||||
|
RSTEP
|
||||||
|
RSTIT
|
||||||
|
RSTNACK
|
||||||
|
RSTRX
|
||||||
|
RSTSTA
|
||||||
|
RSTTX
|
||||||
|
Rsvd
|
||||||
|
RTAR
|
||||||
|
RTCEN
|
||||||
|
RTCSC
|
||||||
|
RTIE
|
||||||
|
RTIF
|
||||||
|
RTIFRC
|
||||||
|
RTMR
|
||||||
|
RTOR
|
||||||
|
RTSEN
|
||||||
|
RTSR
|
||||||
|
RTTC
|
||||||
|
RTVR
|
||||||
|
RVDS
|
||||||
|
RXBRK
|
||||||
|
RXBUFF
|
||||||
|
RXBYTECNT
|
||||||
|
RXDIS
|
||||||
|
Rxed
|
||||||
|
RXEN
|
||||||
|
RXENA
|
||||||
|
RXOVERWRITE
|
||||||
|
RXRDY
|
||||||
|
RXRSM
|
||||||
|
RXSETUP
|
||||||
|
RXSUSP
|
||||||
|
RXSYN
|
||||||
|
RXTEN
|
||||||
|
RXUBR
|
||||||
|
SBYCR
|
||||||
|
SCALL
|
||||||
|
SCBR
|
||||||
|
SCDR
|
||||||
|
SCER
|
||||||
|
SCSR
|
||||||
|
SDCC
|
||||||
|
SECU
|
||||||
|
SENDA
|
||||||
|
SETB
|
||||||
|
SETEN
|
||||||
|
SETPSW
|
||||||
|
SETR
|
||||||
|
setvect
|
||||||
|
SFRC
|
||||||
|
SHLL
|
||||||
|
SHLR
|
||||||
|
SHPR
|
||||||
|
SHTIM
|
||||||
|
SIFIVE
|
||||||
|
sinclude
|
||||||
|
SODR
|
||||||
|
SOFTIRQ
|
||||||
|
SPCK
|
||||||
|
SPIEN
|
||||||
|
SPSR
|
||||||
|
SRCMP
|
||||||
|
SREG
|
||||||
|
SRSDB
|
||||||
|
SSBY
|
||||||
|
SSIR
|
||||||
|
SSKEY
|
||||||
|
staa
|
||||||
|
Stellaris
|
||||||
|
STILM
|
||||||
|
STKPTR
|
||||||
|
stmdb
|
||||||
|
stmia
|
||||||
|
stsr
|
||||||
|
STTBRK
|
||||||
|
STTDLY
|
||||||
|
STTOUT
|
||||||
|
STTTO
|
||||||
|
SVACC
|
||||||
|
svcne
|
||||||
|
SVDIS
|
||||||
|
svlcx
|
||||||
|
SVMST
|
||||||
|
SWAPW
|
||||||
|
SWHSH
|
||||||
|
SWINR
|
||||||
|
SWINT
|
||||||
|
SWINTR
|
||||||
|
SWRST
|
||||||
|
SWTRG
|
||||||
|
synchronise
|
||||||
|
SYSC
|
||||||
|
TACCR
|
||||||
|
TACCTL
|
||||||
|
TACLR
|
||||||
|
TACTL
|
||||||
|
TBCTRL
|
||||||
|
TBLPTRH
|
||||||
|
TBLPTRL
|
||||||
|
TBLPTRU
|
||||||
|
TBLPTRUH
|
||||||
|
TBLPTRUL
|
||||||
|
TBQP
|
||||||
|
TBSY
|
||||||
|
tcclks
|
||||||
|
TCCR
|
||||||
|
TCKPS
|
||||||
|
TCLK
|
||||||
|
TCMR
|
||||||
|
TCOMP
|
||||||
|
TDES
|
||||||
|
TDESMOD
|
||||||
|
TDMI
|
||||||
|
TDRE
|
||||||
|
TEOF
|
||||||
|
TFLG
|
||||||
|
TFMR
|
||||||
|
TGRA
|
||||||
|
THALT
|
||||||
|
TIAO
|
||||||
|
TICKISR
|
||||||
|
TIMFRZ
|
||||||
|
TIMSK
|
||||||
|
TIOA
|
||||||
|
TIOB
|
||||||
|
tmcsr
|
||||||
|
TMCSR
|
||||||
|
TMIF
|
||||||
|
TMKAEN
|
||||||
|
TMKAIF
|
||||||
|
TMKAMK
|
||||||
|
TMMK
|
||||||
|
TMPR
|
||||||
|
TMRLR
|
||||||
|
TNCR
|
||||||
|
TNPR
|
||||||
|
TOSU
|
||||||
|
TOVF
|
||||||
|
TPCS
|
||||||
|
TPFR
|
||||||
|
TRAPA
|
||||||
|
TRGEN
|
||||||
|
TRGSEL
|
||||||
|
TSHR
|
||||||
|
tstfsz
|
||||||
|
TSTP
|
||||||
|
TSTR
|
||||||
|
TTGR
|
||||||
|
TUND
|
||||||
|
TUNDR
|
||||||
|
TWCK
|
||||||
|
TXBUFE
|
||||||
|
TXCOMP
|
||||||
|
TXDIS
|
||||||
|
TXEMPTY
|
||||||
|
TXEN
|
||||||
|
TXENA
|
||||||
|
TXERR
|
||||||
|
TXIE
|
||||||
|
TXIF
|
||||||
|
TXPKTRDY
|
||||||
|
TXRDY
|
||||||
|
TXSYN
|
||||||
|
TXTEN
|
||||||
|
TXUBR
|
||||||
|
TXVC
|
||||||
|
TXVDIS
|
||||||
|
UDCP
|
||||||
|
uncrustify
|
||||||
|
UNRE
|
||||||
|
unsuspended
|
||||||
|
URAD
|
||||||
|
URAT
|
||||||
|
URSTEN
|
||||||
|
URSTIEN
|
||||||
|
URSTS
|
||||||
|
Usart
|
||||||
|
USART
|
||||||
|
USPRG
|
||||||
|
USRIO
|
||||||
|
utest
|
||||||
|
utilises
|
||||||
|
utilising
|
||||||
|
VDDCORE
|
||||||
|
vect
|
||||||
|
VECT
|
||||||
|
VECTACTIVE
|
||||||
|
visualisation
|
||||||
|
vldmdbeq
|
||||||
|
vldmia
|
||||||
|
vldmiaeq
|
||||||
|
VMSRNE
|
||||||
|
vpop
|
||||||
|
VPOPNE
|
||||||
|
vpush
|
||||||
|
VPUSHNE
|
||||||
|
VRPM
|
||||||
|
Vrtc
|
||||||
|
vstmdbeq
|
||||||
|
vstmiaeq
|
||||||
|
VTOR
|
||||||
|
W
|
||||||
|
WAVESEL
|
||||||
|
wavsel
|
||||||
|
Wcolor
|
||||||
|
Wconversion
|
||||||
|
WDCR
|
||||||
|
WDDBGHLT
|
||||||
|
WDDIS
|
||||||
|
WDERR
|
||||||
|
WDFIEN
|
||||||
|
WDIDLEHLT
|
||||||
|
WDMR
|
||||||
|
WDRPROC
|
||||||
|
WDRSTEN
|
||||||
|
WDRSTT
|
||||||
|
WDSR
|
||||||
|
WDTC
|
||||||
|
wdtcon
|
||||||
|
WDUNF
|
||||||
|
Werror
|
||||||
|
WESTAT
|
||||||
|
Weverything
|
||||||
|
Wextra
|
||||||
|
winmm
|
||||||
|
WIZC
|
||||||
|
Wpedantic
|
||||||
|
wrdsp
|
||||||
|
WREG
|
||||||
|
Wunused
|
||||||
|
XEXC
|
||||||
|
XPAR
|
||||||
|
xparameters
|
||||||
|
XPSR
|
||||||
|
XRAM
|
||||||
|
xtal
|
||||||
|
XTENSA
|
3165
.github/lexicon.txt
vendored
3165
.github/lexicon.txt
vendored
File diff suppressed because it is too large
Load diff
2
.github/pull_request_process.md
vendored
2
.github/pull_request_process.md
vendored
|
@ -1,6 +1,6 @@
|
||||||
# Pull Request Process
|
# Pull Request Process
|
||||||
|
|
||||||
This document explains the stages that a Pull Request (PR) goes through when a pull request is submitted to a git repository in the FreeRTOS organization in Github. Before you start a PR, please read and familiarize yourself with [CONTRIBUTING.md](.github/CONTRIBUTING.md)
|
This document explains the stages that a Pull Request (PR) goes through when a pull request is submitted to a git repository in the FreeRTOS organization in Github. Before you start a PR, please read and familiarize yourself with [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||||
|
|
||||||
## ****Terminologies****
|
## ****Terminologies****
|
||||||
|
|
||||||
|
|
8
.github/scripts/kernel_checker.py
vendored
8
.github/scripts/kernel_checker.py
vendored
|
@ -36,7 +36,8 @@ from common.header_checker import HeaderChecker
|
||||||
KERNEL_IGNORED_FILES = [
|
KERNEL_IGNORED_FILES = [
|
||||||
'FreeRTOS-openocd.c',
|
'FreeRTOS-openocd.c',
|
||||||
'Makefile',
|
'Makefile',
|
||||||
'.DS_Store'
|
'.DS_Store',
|
||||||
|
'cspell.config.yaml'
|
||||||
]
|
]
|
||||||
|
|
||||||
KERNEL_IGNORED_EXTENSIONS = [
|
KERNEL_IGNORED_EXTENSIONS = [
|
||||||
|
@ -88,7 +89,10 @@ KERNEL_IGNORED_PATTERNS = [
|
||||||
r'.*portable/IAR/AtmelSAM7S64/.*AT91SAM7.*',
|
r'.*portable/IAR/AtmelSAM7S64/.*AT91SAM7.*',
|
||||||
r'.*portable/GCC/ARM7_AT91SAM7S/.*',
|
r'.*portable/GCC/ARM7_AT91SAM7S/.*',
|
||||||
r'.*portable/MPLAB/PIC18F/stdio.h',
|
r'.*portable/MPLAB/PIC18F/stdio.h',
|
||||||
r'.*portable/ThirdParty/xClang/XCOREAI/*'
|
r'.*portable/ThirdParty/xClang/XCOREAI/*',
|
||||||
|
r'.*IAR/ARM_C*',
|
||||||
|
r'.*IAR/78K0R/*',
|
||||||
|
r'.*CCS/MSP430X/*'
|
||||||
]
|
]
|
||||||
|
|
||||||
KERNEL_THIRD_PARTY_PATTERNS = [
|
KERNEL_THIRD_PARTY_PATTERNS = [
|
||||||
|
|
4
.github/workflows/auto-release.yml
vendored
4
.github/workflows/auto-release.yml
vendored
|
@ -31,14 +31,14 @@ jobs:
|
||||||
|
|
||||||
# Currently FreeRTOS/.github/scripts houses the release script. Download it for upcoming usage
|
# Currently FreeRTOS/.github/scripts houses the release script. Download it for upcoming usage
|
||||||
- name: Checkout FreeRTOS Release Tools
|
- name: Checkout FreeRTOS Release Tools
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
repository: FreeRTOS/FreeRTOS
|
repository: FreeRTOS/FreeRTOS
|
||||||
path: tools
|
path: tools
|
||||||
|
|
||||||
# Simpler git auth if we use checkout action and forward the repo to release script
|
# Simpler git auth if we use checkout action and forward the repo to release script
|
||||||
- name: Checkout FreeRTOS Kernel
|
- name: Checkout FreeRTOS Kernel
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
path: local_kernel
|
path: local_kernel
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
102
.github/workflows/ci.yml
vendored
102
.github/workflows/ci.yml
vendored
|
@ -6,75 +6,53 @@ on:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
jobs:
|
jobs:
|
||||||
spell-check:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout Parent Repo
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
ref: main
|
|
||||||
repository: aws/aws-iot-device-sdk-embedded-C
|
|
||||||
path: main
|
|
||||||
- name: Clone This Repo
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
path: ./kernel
|
|
||||||
- name: Install spell
|
|
||||||
run: |
|
|
||||||
sudo apt-get install spell
|
|
||||||
sudo apt-get install util-linux
|
|
||||||
- name: Check spelling
|
|
||||||
run: |
|
|
||||||
PATH=$PATH:main/tools/spell
|
|
||||||
# Make sure that the portable directory is not included in the spellcheck.
|
|
||||||
sed -i 's/find $DIRNAME/find $DIRNAME -not -path '*portable*'/g' main/tools/spell/find-unknown-comment-words
|
|
||||||
find-unknown-comment-words --directory kernel/ --lexicon ./kernel/.github/lexicon.txt
|
|
||||||
if [ "$?" = "0" ]; then
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
formatting:
|
formatting:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Install Uncrustify
|
- name: Check Formatting of FreeRTOS-Kernel Files
|
||||||
run: sudo apt-get install uncrustify=0.69.0+dfsg1-1build1
|
uses: FreeRTOS/CI-CD-Github-Actions/formatting@main
|
||||||
- name: Run Uncrustify
|
|
||||||
run: |
|
spell-check:
|
||||||
uncrustify --version
|
runs-on: ubuntu-latest
|
||||||
find . portable/MemMang/* portable/Common/* \( -name portable \) -prune -false -o -iname "*.[hc]" -exec uncrustify --check -c .github/uncrustify.cfg {} +
|
steps:
|
||||||
- name: Check For Trailing Whitespace
|
- name: Clone This Repo
|
||||||
run: |
|
uses: actions/checkout@v3
|
||||||
set +e
|
- name: Run spellings check
|
||||||
grep --exclude="*.md" --exclude-dir=".git" -rnI -e "[[:blank:]]$" .
|
uses: FreeRTOS/CI-CD-Github-Actions/spellings@main
|
||||||
if [ "$?" = "0" ]; then
|
with:
|
||||||
echo "Files have trailing whitespace."
|
path: ./
|
||||||
exit 1
|
exclude-files: History.txt
|
||||||
else
|
|
||||||
exit 0
|
link-verifier:
|
||||||
fi
|
runs-on: ubuntu-latest
|
||||||
shell: bash
|
steps:
|
||||||
- name: Check for CRLF
|
- name: Clone This Repo
|
||||||
working-directory: ${{ inputs.path }}
|
uses: actions/checkout@v3
|
||||||
run: |
|
- name: Link Verification
|
||||||
set +e
|
uses: FreeRTOS/CI-CD-Github-Actions/link-verifier@v2
|
||||||
find . -path ./.git -prune -o -exec file {} + | grep "CRLF"
|
|
||||||
if [ "$?" = "0" ]; then
|
|
||||||
echo "Files have CRLF line endings."
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
url-check:
|
url-check:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Clone This Repo
|
- uses: actions/checkout@v3
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
with:
|
||||||
path: ./kernel
|
path: ./kernel
|
||||||
|
|
||||||
- name: URL Checker
|
- name: URL Checker
|
||||||
run: |
|
run: |
|
||||||
bash kernel/.github/actions/url_verifier.sh kernel
|
bash kernel/.github/actions/url_verifier.sh kernel
|
||||||
|
|
||||||
|
verify-manifest:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Run manifest verifier
|
||||||
|
uses: FreeRTOS/CI-CD-GitHub-Actions/manifest-verifier@main
|
||||||
|
with:
|
||||||
|
path: ./
|
||||||
|
fail-on-incorrect-version: true
|
||||||
|
|
4
.github/workflows/git-secrets.yml
vendored
4
.github/workflows/git-secrets.yml
vendored
|
@ -7,11 +7,11 @@ jobs:
|
||||||
git-secrets:
|
git-secrets:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Checkout awslabs/git-secrets
|
- name: Checkout awslabs/git-secrets
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
repository: awslabs/git-secrets
|
repository: awslabs/git-secrets
|
||||||
ref: master
|
ref: master
|
||||||
|
|
4
.github/workflows/kernel-checks.yml
vendored
4
.github/workflows/kernel-checks.yml
vendored
|
@ -18,7 +18,7 @@ jobs:
|
||||||
|
|
||||||
# There is shared code, hosted by FreeRTOS/FreeRTOS, with deps needed by header checker
|
# There is shared code, hosted by FreeRTOS/FreeRTOS, with deps needed by header checker
|
||||||
- name: Checkout FreeRTOS Tools
|
- name: Checkout FreeRTOS Tools
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
repository: FreeRTOS/FreeRTOS
|
repository: FreeRTOS/FreeRTOS
|
||||||
ref: main
|
ref: main
|
||||||
|
@ -26,7 +26,7 @@ jobs:
|
||||||
|
|
||||||
# Checkout user pull request changes
|
# Checkout user pull request changes
|
||||||
- name: Checkout Pull Request
|
- name: Checkout Pull Request
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
path: inspect
|
path: inspect
|
||||||
|
|
||||||
|
|
20
.github/workflows/kernel-demos.yml
vendored
20
.github/workflows/kernel-demos.yml
vendored
|
@ -7,7 +7,7 @@ jobs:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the FreeRTOS/FreeRTOS Repository
|
- name: Checkout the FreeRTOS/FreeRTOS Repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: main
|
ref: main
|
||||||
repository: FreeRTOS/FreeRTOS
|
repository: FreeRTOS/FreeRTOS
|
||||||
|
@ -16,7 +16,7 @@ jobs:
|
||||||
|
|
||||||
# Checkout user pull request changes
|
# Checkout user pull request changes
|
||||||
- name: Checkout Pull Request
|
- name: Checkout Pull Request
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
path: ./FreeRTOS/Source
|
path: ./FreeRTOS/Source
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ jobs:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the FreeRTOS/FreeRTOS Repository
|
- name: Checkout the FreeRTOS/FreeRTOS Repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: main
|
ref: main
|
||||||
repository: FreeRTOS/FreeRTOS
|
repository: FreeRTOS/FreeRTOS
|
||||||
|
@ -45,7 +45,7 @@ jobs:
|
||||||
|
|
||||||
# Checkout user pull request changes
|
# Checkout user pull request changes
|
||||||
- name: Checkout Pull Request
|
- name: Checkout Pull Request
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
path: ./FreeRTOS/Source
|
path: ./FreeRTOS/Source
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the FreeRTOS/FreeRTOS Repository
|
- name: Checkout the FreeRTOS/FreeRTOS Repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: main
|
ref: main
|
||||||
repository: FreeRTOS/FreeRTOS
|
repository: FreeRTOS/FreeRTOS
|
||||||
|
@ -70,7 +70,7 @@ jobs:
|
||||||
|
|
||||||
# Checkout user pull request changes
|
# Checkout user pull request changes
|
||||||
- name: Checkout Pull Request
|
- name: Checkout Pull Request
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
path: ./FreeRTOS/Source
|
path: ./FreeRTOS/Source
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the FreeRTOS/FreeRTOS Repository
|
- name: Checkout the FreeRTOS/FreeRTOS Repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: main
|
ref: main
|
||||||
repository: FreeRTOS/FreeRTOS
|
repository: FreeRTOS/FreeRTOS
|
||||||
|
@ -104,7 +104,7 @@ jobs:
|
||||||
|
|
||||||
# Checkout user pull request changes
|
# Checkout user pull request changes
|
||||||
- name: Checkout Pull Request
|
- name: Checkout Pull Request
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
path: ./FreeRTOS/Source
|
path: ./FreeRTOS/Source
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the FreeRTOS/FreeRTOS Repository
|
- name: Checkout the FreeRTOS/FreeRTOS Repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: main
|
ref: main
|
||||||
repository: FreeRTOS/FreeRTOS
|
repository: FreeRTOS/FreeRTOS
|
||||||
|
@ -146,7 +146,7 @@ jobs:
|
||||||
|
|
||||||
# Checkout user pull request changes
|
# Checkout user pull request changes
|
||||||
- name: Checkout Pull Request
|
- name: Checkout Pull Request
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
path: ./FreeRTOS/Source
|
path: ./FreeRTOS/Source
|
||||||
|
|
||||||
|
|
4
.github/workflows/unit-tests.yml
vendored
4
.github/workflows/unit-tests.yml
vendored
|
@ -6,7 +6,7 @@ jobs:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Parent Repository
|
- name: Checkout Parent Repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: main
|
ref: main
|
||||||
repository: FreeRTOS/FreeRTOS
|
repository: FreeRTOS/FreeRTOS
|
||||||
|
@ -15,7 +15,7 @@ jobs:
|
||||||
|
|
||||||
# Checkout user pull request changes
|
# Checkout user pull request changes
|
||||||
- name: Checkout Pull Request
|
- name: Checkout Pull Request
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
path: ./FreeRTOS/Source
|
path: ./FreeRTOS/Source
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.15)
|
||||||
# FREERTOS_PORT, if not specified and native port detected, uses the native compile.
|
# FREERTOS_PORT, if not specified and native port detected, uses the native compile.
|
||||||
#
|
#
|
||||||
# User is responsible for one library target:
|
# User is responsible for one library target:
|
||||||
# freertos_config ,typcially an INTERFACE library
|
# freertos_config ,typically an INTERFACE library
|
||||||
#
|
#
|
||||||
# DEPRECATED: FREERTOS_CONFIG_FILE_DIRECTORY - but still supported if no freertos_config defined for now.
|
# DEPRECATED: FREERTOS_CONFIG_FILE_DIRECTORY - but still supported if no freertos_config defined for now.
|
||||||
# May be removed at some point in the future.
|
# May be removed at some point in the future.
|
||||||
|
|
63
README.md
63
README.md
|
@ -1,14 +1,28 @@
|
||||||
[](https://github.com/FreeRTOS/FreeRTOS-Kernel/actions/workflows/unit-tests.yml?query=branch%3Amain+event%3Apush+workflow%3A%22CMock+Unit+Tests%22++)
|
[](https://github.com/FreeRTOS/FreeRTOS-Kernel/actions/workflows/unit-tests.yml?query=branch%3Amain+event%3Apush+workflow%3A%22CMock+Unit+Tests%22++)
|
||||||
[](https://codecov.io/gh/FreeRTOS/FreeRTOS-Kernel)
|
[](https://codecov.io/gh/FreeRTOS/FreeRTOS-Kernel)
|
||||||
## Getting started
|
## Getting started
|
||||||
This repository contains FreeRTOS kernel source/header files and kernel ports only. This repository is referenced as a submodule in [FreeRTOS/FreeRTOS](https://github.com/FreeRTOS/FreeRTOS) repository, which contains pre-configured demo application projects under ```FreeRTOS/Demo``` directory.
|
This repository contains FreeRTOS kernel source/header files and kernel
|
||||||
|
ports only. This repository is referenced as a submodule in
|
||||||
|
[FreeRTOS/FreeRTOS](https://github.com/FreeRTOS/FreeRTOS)
|
||||||
|
repository, which contains pre-configured demo application projects under
|
||||||
|
```FreeRTOS/Demo``` directory.
|
||||||
|
|
||||||
The easiest way to use FreeRTOS is to start with one of the pre-configured demo application projects. That way you will have the correct FreeRTOS source files included, and the correct include paths configured. Once a demo application is building and executing you can remove the demo application files, and start to add in your own application source files. See the [FreeRTOS Kernel Quick Start Guide](https://www.FreeRTOS.org/FreeRTOS-quick-start-guide.html) for detailed instructions and other useful links.
|
The easiest way to use FreeRTOS is to start with one of the pre-configured demo
|
||||||
|
application projects. That way you will have the correct FreeRTOS source files
|
||||||
|
included, and the correct include paths configured. Once a demo application is
|
||||||
|
building and executing you can remove the demo application files, and start to
|
||||||
|
add in your own application source files. See the
|
||||||
|
[FreeRTOS Kernel Quick Start Guide](https://www.FreeRTOS.org/FreeRTOS-quick-start-guide.html)
|
||||||
|
for detailed instructions and other useful links.
|
||||||
|
|
||||||
Additionally, for FreeRTOS kernel feature information refer to the [Developer Documentation](https://www.FreeRTOS.org/features.html), and [API Reference](https://www.FreeRTOS.org/a00106.html).
|
Additionally, for FreeRTOS kernel feature information refer to the
|
||||||
|
[Developer Documentation](https://www.FreeRTOS.org/features.html),
|
||||||
|
and [API Reference](https://www.FreeRTOS.org/a00106.html).
|
||||||
|
|
||||||
### Getting help
|
### Getting help
|
||||||
If you have any questions or need assistance troubleshooting your FreeRTOS project, we have an active community that can help on the [FreeRTOS Community Support Forum](https://forums.freertos.org).
|
If you have any questions or need assistance troubleshooting your FreeRTOS project,
|
||||||
|
we have an active community that can help on the
|
||||||
|
[FreeRTOS Community Support Forum](https://forums.freertos.org).
|
||||||
|
|
||||||
## To consume FreeRTOS-Kernel
|
## To consume FreeRTOS-Kernel
|
||||||
|
|
||||||
|
@ -99,22 +113,49 @@ See the readme file in the ```./portable``` directory for more information.
|
||||||
- The ```./include``` directory contains the real time kernel header files.
|
- The ```./include``` directory contains the real time kernel header files.
|
||||||
|
|
||||||
### Code Formatting
|
### Code Formatting
|
||||||
FreeRTOS files are formatted using the "uncrustify" tool. The configuration file used by uncrustify can be found in the [.github/uncrustify.cfg](.github/uncrustify.cfg) file.
|
FreeRTOS files are formatted using the
|
||||||
|
"[uncrustify](https://github.com/uncrustify/uncrustify)" tool.
|
||||||
|
The configuration file used by uncrustify can be found in the
|
||||||
|
[FreeRTOS/CI-CD-GitHub-Actions's](https://github.com/FreeRTOS/CI-CD-Github-Actions)
|
||||||
|
[uncrustify.cfg](https://github.com/FreeRTOS/CI-CD-Github-Actions/tree/main/formatting)
|
||||||
|
file.
|
||||||
|
|
||||||
### Line Endings
|
### Line Endings
|
||||||
File checked into the FreeRTOS-Kernel repository use unix-style LF line endings for the best compatibility with git.
|
File checked into the FreeRTOS-Kernel repository use unix-style LF line endings
|
||||||
|
for the best compatibility with git.
|
||||||
|
|
||||||
For optimal compatibility with Microsoft Windows tools, it is best to enable the git autocrlf feature. You can enable this setting for the current repository using the following command:
|
For optimal compatibility with Microsoft Windows tools, it is best to enable
|
||||||
|
the git autocrlf feature. You can enable this setting for the current
|
||||||
|
repository using the following command:
|
||||||
```
|
```
|
||||||
git config core.autocrlf true
|
git config core.autocrlf true
|
||||||
```
|
```
|
||||||
|
|
||||||
### Git History Optimizations
|
### Git History Optimizations
|
||||||
Some commits in this repository perform large refactors which touch many lines and lead to unwanted behavior when using the `git blame` command. You can configure git to ignore the list of large refactor commits in this repository with the following command:
|
Some commits in this repository perform large refactors which touch many lines
|
||||||
|
and lead to unwanted behavior when using the `git blame` command. You can
|
||||||
|
configure git to ignore the list of large refactor commits in this repository
|
||||||
|
with the following command:
|
||||||
```
|
```
|
||||||
git config blame.ignoreRevsFile .git-blame-ignore-revs
|
git config blame.ignoreRevsFile .git-blame-ignore-revs
|
||||||
```
|
```
|
||||||
|
|
||||||
### Spelling
|
### Spelling and Formatting
|
||||||
*lexicon.txt* contains words that are not traditionally found in an English dictionary. It is used by the spellchecker to verify the various jargon, variable names, and other odd words used in the FreeRTOS code base. If your pull request fails to pass the spelling and you believe this is a mistake, then add the word to *lexicon.txt*.
|
We recommend using [Visual Studio Code](https://code.visualstudio.com),
|
||||||
Note that only the FreeRTOS Kernel source files are checked for proper spelling, the portable section is ignored.
|
commonly referred to as VSCode, when working on the FreeRTOS-Kernel.
|
||||||
|
The FreeRTOS-Kernel also uses [cSpell](https://cspell.org/) as part of its
|
||||||
|
spelling check. The config file for which can be found at [cspell.config.yaml](cspell.config.yaml)
|
||||||
|
There is additionally a
|
||||||
|
[cSpell plugin for VSCode](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)
|
||||||
|
that can be used as well.
|
||||||
|
*[.cSpellWords.txt](.github/.cSpellWords.txt)* contains words that are not
|
||||||
|
traditionally found in an English dictionary. It is used by the spellchecker
|
||||||
|
to verify the various jargon, variable names, and other odd words used in the
|
||||||
|
FreeRTOS code base are correct. If your pull request fails to pass the spelling
|
||||||
|
and you believe this is a mistake, then add the word to
|
||||||
|
*[.cSpellWords.txt](.github/.cSpellWords.txt)*. When adding a word please
|
||||||
|
then sort the list, which can be done by running the bash command:
|
||||||
|
`sort -u .cSpellWords.txt -o .cSpellWords.txt`
|
||||||
|
Note that only the FreeRTOS-Kernel Source Files, [include](include),
|
||||||
|
[portable/MemMang](portable/MemMang), and [portable/Common](portable/Common)
|
||||||
|
files are checked for proper spelling, and formatting at this time.
|
||||||
|
|
31
cspell.config.yaml
Normal file
31
cspell.config.yaml
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
---
|
||||||
|
$schema: https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json
|
||||||
|
version: '0.2'
|
||||||
|
# Allows things like stringLength
|
||||||
|
allowCompoundWords: true
|
||||||
|
|
||||||
|
# Read files not to spell check from the git ignore
|
||||||
|
useGitignore: true
|
||||||
|
|
||||||
|
# Language settings for C
|
||||||
|
languageSettings:
|
||||||
|
- caseSensitive: false
|
||||||
|
enabled: true
|
||||||
|
languageId: c
|
||||||
|
locale: "*"
|
||||||
|
|
||||||
|
# Add a dictionary, and the path to the word list
|
||||||
|
dictionaryDefinitions:
|
||||||
|
- name: freertos-words
|
||||||
|
path: '.github/.cSpellWords.txt'
|
||||||
|
addWords: true
|
||||||
|
|
||||||
|
dictionaries:
|
||||||
|
- freertos-words
|
||||||
|
|
||||||
|
# Paths and files to ignore
|
||||||
|
ignorePaths:
|
||||||
|
- 'dependency'
|
||||||
|
- 'docs'
|
||||||
|
- 'ThirdParty'
|
||||||
|
- 'History.txt'
|
|
@ -1,4 +1,4 @@
|
||||||
This directory tree contains the master copy of the FreeeRTOS Armv8-M and
|
This directory tree contains the master copy of the FreeRTOS Armv8-M and
|
||||||
Armv8.1-M ports.
|
Armv8.1-M ports.
|
||||||
Do not use the files located here! These file are copied into separate
|
Do not use the files located here! These file are copied into separate
|
||||||
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NNN directories prior to each
|
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NNN directories prior to each
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -48,9 +48,9 @@
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M23"
|
#define portARCH_NAME "Cortex-M23"
|
||||||
#define portHAS_ARMV8M_MAIN_EXTENSION 0
|
#define portHAS_ARMV8M_MAIN_EXTENSION 0
|
||||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ARMv8-M common port configurations. */
|
/* ARMv8-M common port configurations. */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -46,127 +46,127 @@
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" program_mpu_first_task: \n"
|
" program_mpu_first_task: \n"
|
||||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||||
" \n"
|
" \n"
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
" movs r3, #1 \n" /* r3 = 1. */
|
" movs r3, #1 \n" /* r3 = 1. */
|
||||||
" bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */
|
" bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */
|
||||||
" str r2, [r1] \n" /* Disable MPU. */
|
" str r2, [r1] \n" /* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r1, [r2] \n" /* Program MAIR0. */
|
" str r1, [r2] \n" /* Program MAIR0. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||||
" \n"
|
" \n"
|
||||||
" movs r3, #4 \n" /* r3 = 4. */
|
" movs r3, #4 \n" /* r3 = 4. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||||
" ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */
|
||||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */
|
" stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */
|
||||||
" movs r3, #5 \n" /* r3 = 5. */
|
" movs r3, #5 \n" /* r3 = 5. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 5. */
|
" str r3, [r1] \n" /* Program RNR = 5. */
|
||||||
" ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */
|
||||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */
|
" stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */
|
||||||
" movs r3, #6 \n" /* r3 = 6. */
|
" movs r3, #6 \n" /* r3 = 6. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 6. */
|
" str r3, [r1] \n" /* Program RNR = 6. */
|
||||||
" ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */
|
||||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */
|
" stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */
|
||||||
" movs r3, #7 \n" /* r3 = 6. */
|
" movs r3, #7 \n" /* r3 = 6. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 7. */
|
" str r3, [r1] \n" /* Program RNR = 7. */
|
||||||
" ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */
|
||||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */
|
" stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
" movs r3, #1 \n" /* r3 = 1. */
|
" movs r3, #1 \n" /* r3 = 1. */
|
||||||
" orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */
|
" orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */
|
||||||
" str r2, [r1] \n" /* Enable MPU. */
|
" str r2, [r1] \n" /* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n" /* Force memory writes before continuing. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_context_first_task: \n"
|
" restore_context_first_task: \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_special_regs_first_task: \n"
|
" restore_special_regs_first_task: \n"
|
||||||
" subs r1, #16 \n"
|
" subs r1, #16 \n"
|
||||||
" ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */
|
" ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */
|
||||||
" subs r1, #16 \n"
|
" subs r1, #16 \n"
|
||||||
" msr psp, r2 \n"
|
" msr psp, r2 \n"
|
||||||
" msr psplim, r3 \n"
|
" msr psplim, r3 \n"
|
||||||
" msr control, r4 \n"
|
" msr control, r4 \n"
|
||||||
" mov lr, r5 \n"
|
" mov lr, r5 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" restore_general_regs_first_task: \n"
|
" restore_general_regs_first_task: \n"
|
||||||
" subs r1, #32 \n"
|
" subs r1, #32 \n"
|
||||||
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */
|
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */
|
||||||
" stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */
|
" stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */
|
||||||
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */
|
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */
|
||||||
" stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */
|
" stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */
|
||||||
" subs r1, #48 \n"
|
" subs r1, #48 \n"
|
||||||
" ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */
|
" ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */
|
||||||
" mov r8, r4 \n" /* r8 = r4. */
|
" mov r8, r4 \n" /* r8 = r4. */
|
||||||
" mov r9, r5 \n" /* r9 = r5. */
|
" mov r9, r5 \n" /* r9 = r5. */
|
||||||
" mov r10, r6 \n" /* r10 = r6. */
|
" mov r10, r6 \n" /* r10 = r6. */
|
||||||
" mov r11, r7 \n" /* r11 = r7. */
|
" mov r11, r7 \n" /* r11 = r7. */
|
||||||
" subs r1, #32 \n"
|
" subs r1, #32 \n"
|
||||||
" ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */
|
" ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */
|
||||||
" subs r1, #16 \n"
|
" subs r1, #16 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" restore_context_done_first_task: \n"
|
" restore_context_done_first_task: \n"
|
||||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||||
" xRNRConst2: .word 0xe000ed98 \n"
|
" xRNRConst2: .word 0xe000ed98 \n"
|
||||||
" xRBARConst2: .word 0xe000ed9c \n"
|
" xRBARConst2: .word 0xe000ed9c \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||||
" ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
" ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||||
" msr psplim, r1 \n"/* Set this task's PSPLIM value. */
|
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
||||||
" movs r1, #2 \n"/* r1 = 2. */
|
" movs r1, #2 \n" /* r1 = 2. */
|
||||||
" msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */
|
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||||
" adds r0, #32 \n"/* Discard everything up to r0. */
|
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx r2 \n"/* Finally, branch to EXC_RETURN. */
|
" bx r2 \n" /* Finally, branch to EXC_RETURN. */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -177,15 +177,15 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
" movs r1, #1 \n"/* r1 = 1. */
|
" movs r1, #1 \n" /* r1 = 1. */
|
||||||
" tst r0, r1 \n"/* Perform r0 & r1 (bitwise AND) and update the conditions flag. */
|
" tst r0, r1 \n" /* Perform r0 & r1 (bitwise AND) and update the conditions flag. */
|
||||||
" beq running_privileged \n"/* If the result of previous AND operation was 0, branch. */
|
" beq running_privileged \n" /* If the result of previous AND operation was 0, branch. */
|
||||||
" movs r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
" movs r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||||
" bx lr \n"/* Return. */
|
" bx lr \n" /* Return. */
|
||||||
" running_privileged: \n"
|
" running_privileged: \n"
|
||||||
" movs r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
" movs r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||||
" bx lr \n"/* Return. */
|
" bx lr \n" /* Return. */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
::: "r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
|
@ -199,11 +199,11 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, control \n"/* Read the CONTROL register. */
|
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||||
" movs r1, #1 \n"/* r1 = 1. */
|
" movs r1, #1 \n" /* r1 = 1. */
|
||||||
" bics r0, r1 \n"/* Clear the bit 0. */
|
" bics r0, r1 \n" /* Clear the bit 0. */
|
||||||
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||||
" bx lr \n"/* Return to the caller. */
|
" bx lr \n" /* Return to the caller. */
|
||||||
::: "r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -215,11 +215,11 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
" movs r1, #1 \n"/* r1 = 1. */
|
" movs r1, #1 \n" /* r1 = 1. */
|
||||||
" orrs r0, r1 \n"/* r0 = r0 | r1. */
|
" orrs r0, r1 \n" /* r0 = r0 | r1. */
|
||||||
" msr control, r0 \n"/* CONTROL = r0. */
|
" msr control, r0 \n" /* CONTROL = r0. */
|
||||||
" bx lr \n"/* Return to the caller. */
|
" bx lr \n" /* Return to the caller. */
|
||||||
::: "r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -231,14 +231,14 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
||||||
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
||||||
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
||||||
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||||
" cpsie i \n"/* Globally enable interrupts. */
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" svc %0 \n"/* System call to start the first task. */
|
" svc %0 \n" /* System call to start the first task. */
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
|
@ -277,254 +277,254 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||||
" ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */
|
" ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */
|
||||||
" mrs r2, psp \n" /* r2 = PSP. */
|
" mrs r2, psp \n" /* r2 = PSP. */
|
||||||
" \n"
|
" \n"
|
||||||
" save_general_regs: \n"
|
" save_general_regs: \n"
|
||||||
" stmia r1!, {r4-r7} \n" /* Store r4-r7. */
|
" stmia r1!, {r4-r7} \n" /* Store r4-r7. */
|
||||||
" mov r4, r8 \n" /* r4 = r8. */
|
" mov r4, r8 \n" /* r4 = r8. */
|
||||||
" mov r5, r9 \n" /* r5 = r9. */
|
" mov r5, r9 \n" /* r5 = r9. */
|
||||||
" mov r6, r10 \n" /* r6 = r10. */
|
" mov r6, r10 \n" /* r6 = r10. */
|
||||||
" mov r7, r11 \n" /* r7 = r11. */
|
" mov r7, r11 \n" /* r7 = r11. */
|
||||||
" stmia r1!, {r4-r7} \n" /* Store r8-r11. */
|
" stmia r1!, {r4-r7} \n" /* Store r8-r11. */
|
||||||
" ldmia r2!, {r4-r7} \n" /* Copy half of the hardware saved context into r4-r7. */
|
" ldmia r2!, {r4-r7} \n" /* Copy half of the hardware saved context into r4-r7. */
|
||||||
" stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */
|
" stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */
|
||||||
" ldmia r2!, {r4-r7} \n" /* Copy rest half of the hardware saved context into r4-r7. */
|
" ldmia r2!, {r4-r7} \n" /* Copy rest half of the hardware saved context into r4-r7. */
|
||||||
" stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */
|
" stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */
|
||||||
" \n"
|
" \n"
|
||||||
" save_special_regs: \n"
|
" save_special_regs: \n"
|
||||||
" mrs r2, psp \n" /* r2 = PSP. */
|
" mrs r2, psp \n" /* r2 = PSP. */
|
||||||
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
||||||
" mrs r4, control \n" /* r4 = CONTROL. */
|
" mrs r4, control \n" /* r4 = CONTROL. */
|
||||||
" mov r5, lr \n" /* r5 = LR. */
|
" mov r5, lr \n" /* r5 = LR. */
|
||||||
" stmia r1!, {r2-r5} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
" stmia r1!, {r2-r5} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||||
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" select_next_task: \n"
|
" select_next_task: \n"
|
||||||
" cpsid i \n"
|
" cpsid i \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" cpsie i \n"
|
" cpsie i \n"
|
||||||
" \n"
|
" \n"
|
||||||
" program_mpu: \n"
|
" program_mpu: \n"
|
||||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||||
" \n"
|
" \n"
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
" movs r3, #1 \n" /* r3 = 1. */
|
" movs r3, #1 \n" /* r3 = 1. */
|
||||||
" bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */
|
" bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */
|
||||||
" str r2, [r1] \n" /* Disable MPU. */
|
" str r2, [r1] \n" /* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r1, [r2] \n" /* Program MAIR0. */
|
" str r1, [r2] \n" /* Program MAIR0. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||||
" \n"
|
" \n"
|
||||||
" movs r3, #4 \n" /* r3 = 4. */
|
" movs r3, #4 \n" /* r3 = 4. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||||
" ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */
|
||||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */
|
" stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */
|
||||||
" movs r3, #5 \n" /* r3 = 5. */
|
" movs r3, #5 \n" /* r3 = 5. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 5. */
|
" str r3, [r1] \n" /* Program RNR = 5. */
|
||||||
" ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */
|
||||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */
|
" stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */
|
||||||
" movs r3, #6 \n" /* r3 = 6. */
|
" movs r3, #6 \n" /* r3 = 6. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 6. */
|
" str r3, [r1] \n" /* Program RNR = 6. */
|
||||||
" ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */
|
||||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */
|
" stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */
|
||||||
" movs r3, #7 \n" /* r3 = 6. */
|
" movs r3, #7 \n" /* r3 = 6. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 7. */
|
" str r3, [r1] \n" /* Program RNR = 7. */
|
||||||
" ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */
|
||||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */
|
" stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
" movs r3, #1 \n" /* r3 = 1. */
|
" movs r3, #1 \n" /* r3 = 1. */
|
||||||
" orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */
|
" orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */
|
||||||
" str r2, [r1] \n" /* Enable MPU. */
|
" str r2, [r1] \n" /* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n" /* Force memory writes before continuing. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_context: \n"
|
" restore_context: \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_special_regs: \n"
|
" restore_special_regs: \n"
|
||||||
" subs r1, #16 \n"
|
" subs r1, #16 \n"
|
||||||
" ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */
|
" ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */
|
||||||
" subs r1, #16 \n"
|
" subs r1, #16 \n"
|
||||||
" msr psp, r2 \n"
|
" msr psp, r2 \n"
|
||||||
" msr psplim, r3 \n"
|
" msr psplim, r3 \n"
|
||||||
" msr control, r4 \n"
|
" msr control, r4 \n"
|
||||||
" mov lr, r5 \n"
|
" mov lr, r5 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" restore_general_regs: \n"
|
" restore_general_regs: \n"
|
||||||
" subs r1, #32 \n"
|
" subs r1, #32 \n"
|
||||||
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */
|
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */
|
||||||
" stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */
|
" stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */
|
||||||
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */
|
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */
|
||||||
" stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */
|
" stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */
|
||||||
" subs r1, #48 \n"
|
" subs r1, #48 \n"
|
||||||
" ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */
|
" ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */
|
||||||
" mov r8, r4 \n" /* r8 = r4. */
|
" mov r8, r4 \n" /* r8 = r4. */
|
||||||
" mov r9, r5 \n" /* r9 = r5. */
|
" mov r9, r5 \n" /* r9 = r5. */
|
||||||
" mov r10, r6 \n" /* r10 = r6. */
|
" mov r10, r6 \n" /* r10 = r6. */
|
||||||
" mov r11, r7 \n" /* r11 = r7. */
|
" mov r11, r7 \n" /* r11 = r7. */
|
||||||
" subs r1, #32 \n"
|
" subs r1, #32 \n"
|
||||||
" ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */
|
" ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */
|
||||||
" subs r1, #16 \n"
|
" subs r1, #16 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" restore_context_done: \n"
|
" restore_context_done: \n"
|
||||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||||
" xRNRConst: .word 0xe000ed98 \n"
|
" xRNRConst: .word 0xe000ed98 \n"
|
||||||
" xRBARConst: .word 0xe000ed9c \n"
|
" xRBARConst: .word 0xe000ed9c \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, psp \n"/* Read PSP in r0. */
|
" mrs r0, psp \n" /* Read PSP in r0. */
|
||||||
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||||
" subs r0, r0, #40 \n"/* Make space for PSPLIM, LR and the remaining registers on the stack. */
|
" subs r0, r0, #40 \n" /* Make space for PSPLIM, LR and the remaining registers on the stack. */
|
||||||
" str r0, [r1] \n"/* Save the new top of stack in TCB. */
|
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
|
||||||
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||||
" stmia r0!, {r2-r7} \n"/* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */
|
" stmia r0!, {r2-r7} \n" /* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */
|
||||||
" mov r4, r8 \n"/* r4 = r8. */
|
" mov r4, r8 \n" /* r4 = r8. */
|
||||||
" mov r5, r9 \n"/* r5 = r9. */
|
" mov r5, r9 \n" /* r5 = r9. */
|
||||||
" mov r6, r10 \n"/* r6 = r10. */
|
" mov r6, r10 \n" /* r6 = r10. */
|
||||||
" mov r7, r11 \n"/* r7 = r11. */
|
" mov r7, r11 \n" /* r7 = r11. */
|
||||||
" stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */
|
" stmia r0!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
|
||||||
" \n"
|
" \n"
|
||||||
" cpsid i \n"
|
" cpsid i \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" cpsie i \n"
|
" cpsie i \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||||
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, r0, #24 \n"/* Move to the high registers. */
|
" adds r0, r0, #24 \n" /* Move to the high registers. */
|
||||||
" ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */
|
" ldmia r0!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */
|
||||||
" mov r8, r4 \n"/* r8 = r4. */
|
" mov r8, r4 \n" /* r8 = r4. */
|
||||||
" mov r9, r5 \n"/* r9 = r5. */
|
" mov r9, r5 \n" /* r9 = r5. */
|
||||||
" mov r10, r6 \n"/* r10 = r6. */
|
" mov r10, r6 \n" /* r10 = r6. */
|
||||||
" mov r11, r7 \n"/* r11 = r7. */
|
" mov r11, r7 \n" /* r11 = r7. */
|
||||||
" msr psp, r0 \n"/* Remember the new top of stack for the task. */
|
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
||||||
" subs r0, r0, #40 \n"/* Move to the starting of the saved context. */
|
" subs r0, r0, #40 \n" /* Move to the starting of the saved context. */
|
||||||
" ldmia r0!, {r2-r7} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */
|
" ldmia r0!, {r2-r7} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */
|
||||||
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
|
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
||||||
" bx r3 \n"
|
" bx r3 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
".syntax unified \n"
|
".syntax unified \n"
|
||||||
".extern vPortSVCHandler_C \n"
|
".extern vPortSVCHandler_C \n"
|
||||||
".extern vSystemCallEnter \n"
|
".extern vSystemCallEnter \n"
|
||||||
".extern vSystemCallEnter_1 \n"
|
".extern vSystemCallEnter_1 \n"
|
||||||
".extern vSystemCallExit \n"
|
".extern vSystemCallExit \n"
|
||||||
" \n"
|
" \n"
|
||||||
"movs r0, #4 \n"
|
"movs r0, #4 \n"
|
||||||
"mov r1, lr \n"
|
"mov r1, lr \n"
|
||||||
"tst r0, r1 \n"
|
"tst r0, r1 \n"
|
||||||
"beq stack_on_msp \n"
|
"beq stack_on_msp \n"
|
||||||
"stack_on_psp: \n"
|
"stack_on_psp: \n"
|
||||||
" mrs r0, psp \n"
|
" mrs r0, psp \n"
|
||||||
" b route_svc \n"
|
" b route_svc \n"
|
||||||
"stack_on_msp: \n"
|
"stack_on_msp: \n"
|
||||||
" mrs r0, msp \n"
|
" mrs r0, msp \n"
|
||||||
" b route_svc \n"
|
" b route_svc \n"
|
||||||
" \n"
|
" \n"
|
||||||
"route_svc: \n"
|
"route_svc: \n"
|
||||||
" ldr r2, [r0, #24] \n"
|
" ldr r2, [r0, #24] \n"
|
||||||
" subs r2, #2 \n"
|
" subs r2, #2 \n"
|
||||||
" ldrb r3, [r2, #0] \n"
|
" ldrb r3, [r2, #0] \n"
|
||||||
" cmp r3, %0 \n"
|
" cmp r3, %0 \n"
|
||||||
" beq system_call_enter \n"
|
" beq system_call_enter \n"
|
||||||
" cmp r3, %1 \n"
|
" cmp r3, %1 \n"
|
||||||
" beq system_call_enter_1 \n"
|
" beq system_call_enter_1 \n"
|
||||||
" cmp r3, %2 \n"
|
" cmp r3, %2 \n"
|
||||||
" beq system_call_exit \n"
|
" beq system_call_exit \n"
|
||||||
" b vPortSVCHandler_C \n"
|
" b vPortSVCHandler_C \n"
|
||||||
" \n"
|
" \n"
|
||||||
"system_call_enter: \n"
|
"system_call_enter: \n"
|
||||||
" b vSystemCallEnter \n"
|
" b vSystemCallEnter \n"
|
||||||
"system_call_enter_1: \n"
|
"system_call_enter_1: \n"
|
||||||
" b vSystemCallEnter_1 \n"
|
" b vSystemCallEnter_1 \n"
|
||||||
"system_call_exit: \n"
|
"system_call_exit: \n"
|
||||||
" b vSystemCallExit \n"
|
" b vSystemCallExit \n"
|
||||||
" \n"
|
" \n"
|
||||||
: /* No outputs. */
|
: /* No outputs. */
|
||||||
:"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
: "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||||
: "r0", "r1", "r2", "r3", "memory"
|
: "r0", "r1", "r2", "r3", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" movs r0, #4 \n"
|
" movs r0, #4 \n"
|
||||||
" mov r1, lr \n"
|
" mov r1, lr \n"
|
||||||
" tst r0, r1 \n"
|
" tst r0, r1 \n"
|
||||||
" beq stacking_used_msp \n"
|
" beq stacking_used_msp \n"
|
||||||
" mrs r0, psp \n"
|
" mrs r0, psp \n"
|
||||||
" ldr r2, svchandler_address_const \n"
|
" ldr r2, svchandler_address_const \n"
|
||||||
" bx r2 \n"
|
" bx r2 \n"
|
||||||
" stacking_used_msp: \n"
|
" stacking_used_msp: \n"
|
||||||
" mrs r0, msp \n"
|
" mrs r0, msp \n"
|
||||||
" ldr r2, svchandler_address_const \n"
|
" ldr r2, svchandler_address_const \n"
|
||||||
" bx r2 \n"
|
" bx r2 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
@ -48,9 +48,9 @@
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M23"
|
#define portARCH_NAME "Cortex-M23"
|
||||||
#define portHAS_ARMV8M_MAIN_EXTENSION 0
|
#define portHAS_ARMV8M_MAIN_EXTENSION 0
|
||||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ARMv8-M common port configurations. */
|
/* ARMv8-M common port configurations. */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -42,116 +42,116 @@
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" program_mpu_first_task: \n"
|
" program_mpu_first_task: \n"
|
||||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */
|
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||||
" str r2, [r1] \n" /* Disable MPU. */
|
" str r2, [r1] \n" /* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r1, [r2] \n" /* Program MAIR0. */
|
" str r1, [r2] \n" /* Program MAIR0. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" \n"
|
" \n"
|
||||||
" movs r3, #4 \n" /* r3 = 4. */
|
" movs r3, #4 \n" /* r3 = 4. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
" \n"
|
" \n"
|
||||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
" movs r3, #8 \n" /* r3 = 8. */
|
" movs r3, #8 \n" /* r3 = 8. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
" movs r3, #12 \n" /* r3 = 12. */
|
" movs r3, #12 \n" /* r3 = 12. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
" orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */
|
" orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */
|
||||||
" str r2, [r1] \n" /* Enable MPU. */
|
" str r2, [r1] \n" /* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n" /* Force memory writes before continuing. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_context_first_task: \n"
|
" restore_context_first_task: \n"
|
||||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_special_regs_first_task: \n"
|
" restore_special_regs_first_task: \n"
|
||||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||||
" msr psp, r3 \n"
|
" msr psp, r3 \n"
|
||||||
" msr psplim, r4 \n"
|
" msr psplim, r4 \n"
|
||||||
" msr control, r5 \n"
|
" msr control, r5 \n"
|
||||||
" ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
" ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_general_regs_first_task: \n"
|
" restore_general_regs_first_task: \n"
|
||||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_context_done_first_task: \n"
|
" restore_context_done_first_task: \n"
|
||||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||||
" mov r0, #0 \n"
|
" mov r0, #0 \n"
|
||||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
" xSecureContextConst2: .word xSecureContext \n"
|
" xSecureContextConst2: .word xSecureContext \n"
|
||||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||||
" xRNRConst2: .word 0xe000ed98 \n"
|
" xRNRConst2: .word 0xe000ed98 \n"
|
||||||
" xRBARConst2: .word 0xe000ed9c \n"
|
" xRBARConst2: .word 0xe000ed9c \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
||||||
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||||
" ldr r4, xSecureContextConst2 \n"
|
" ldr r4, xSecureContextConst2 \n"
|
||||||
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
|
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
|
||||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
||||||
" movs r1, #2 \n" /* r1 = 2. */
|
" movs r1, #2 \n" /* r1 = 2. */
|
||||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" mov r0, #0 \n"
|
" mov r0, #0 \n"
|
||||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
"xSecureContextConst2: .word xSecureContext \n"
|
"xSecureContextConst2: .word xSecureContext \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -162,12 +162,12 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
" tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||||
" ite ne \n"
|
" ite ne \n"
|
||||||
" movne r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
" movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||||
" moveq r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
" moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||||
" bx lr \n"/* Return. */
|
" bx lr \n" /* Return. */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
::: "r0", "memory"
|
::: "r0", "memory"
|
||||||
|
@ -181,10 +181,10 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, control \n"/* Read the CONTROL register. */
|
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||||
" bic r0, #1 \n"/* Clear the bit 0. */
|
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||||
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||||
" bx lr \n"/* Return to the caller. */
|
" bx lr \n" /* Return to the caller. */
|
||||||
::: "r0", "memory"
|
::: "r0", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -196,10 +196,10 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
" orr r0, #1 \n"/* r0 = r0 | 1. */
|
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||||
" msr control, r0 \n"/* CONTROL = r0. */
|
" msr control, r0 \n" /* CONTROL = r0. */
|
||||||
" bx lr \n"/* Return to the caller. */
|
" bx lr \n" /* Return to the caller. */
|
||||||
::: "r0", "memory"
|
::: "r0", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -211,15 +211,15 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
||||||
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
||||||
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
||||||
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||||
" cpsie i \n"/* Globally enable interrupts. */
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
" cpsie f \n"
|
" cpsie f \n"
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" svc %0 \n"/* System call to start the first task. */
|
" svc %0 \n" /* System call to start the first task. */
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
|
@ -235,12 +235,12 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */
|
" mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
|
||||||
" mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
" mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
" msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
" msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx lr \n"/* Return. */
|
" bx lr \n" /* Return. */
|
||||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -252,10 +252,10 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" msr basepri, r0 \n"/* basepri = ulMask. */
|
" msr basepri, r0 \n" /* basepri = ulMask. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx lr \n"/* Return. */
|
" bx lr \n" /* Return. */
|
||||||
::: "memory"
|
::: "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -263,320 +263,320 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" .extern SecureContext_SaveContext \n"
|
" .extern SecureContext_SaveContext \n"
|
||||||
" .extern SecureContext_LoadContext \n"
|
" .extern SecureContext_LoadContext \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||||
" ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */
|
" ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */
|
||||||
" \n"
|
" \n"
|
||||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||||
" save_s_context: \n"
|
" save_s_context: \n"
|
||||||
" push {r0-r2, lr} \n"
|
" push {r0-r2, lr} \n"
|
||||||
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||||
" pop {r0-r2, lr} \n"
|
" pop {r0-r2, lr} \n"
|
||||||
" \n"
|
" \n"
|
||||||
" save_ns_context: \n"
|
" save_ns_context: \n"
|
||||||
" mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
|
" mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
|
||||||
" lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
" lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
" bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
" bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||||
" \n"
|
" \n"
|
||||||
" save_general_regs: \n"
|
" save_general_regs: \n"
|
||||||
" mrs r3, psp \n"
|
" mrs r3, psp \n"
|
||||||
" \n"
|
" \n"
|
||||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
" add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */
|
" add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */
|
||||||
" tst lr, #0x10 \n"
|
" tst lr, #0x10 \n"
|
||||||
" ittt eq \n"
|
" ittt eq \n"
|
||||||
" vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */
|
" vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */
|
||||||
" vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
" vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||||
" vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */
|
" vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||||
" sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */
|
" sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
" \n"
|
" \n"
|
||||||
" stmia r2!, {r4-r11} \n" /* Store r4-r11. */
|
" stmia r2!, {r4-r11} \n" /* Store r4-r11. */
|
||||||
" ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
" ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||||
" stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */
|
" stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||||
" \n"
|
" \n"
|
||||||
" save_special_regs: \n"
|
" save_special_regs: \n"
|
||||||
" mrs r3, psp \n" /* r3 = PSP. */
|
" mrs r3, psp \n" /* r3 = PSP. */
|
||||||
" mrs r4, psplim \n" /* r4 = PSPLIM. */
|
" mrs r4, psplim \n" /* r4 = PSPLIM. */
|
||||||
" mrs r5, control \n" /* r5 = CONTROL. */
|
" mrs r5, control \n" /* r5 = CONTROL. */
|
||||||
" stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
" stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||||
" str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
" str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" select_next_task: \n"
|
" select_next_task: \n"
|
||||||
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
||||||
" msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
" msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" mov r0, #0 \n" /* r0 = 0. */
|
" mov r0, #0 \n" /* r0 = 0. */
|
||||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||||
" \n"
|
" \n"
|
||||||
" program_mpu: \n"
|
" program_mpu: \n"
|
||||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||||
" \n"
|
" \n"
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||||
" str r2, [r1] \n" /* Disable MPU. */
|
" str r2, [r1] \n" /* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r1, [r2] \n" /* Program MAIR0. */
|
" str r1, [r2] \n" /* Program MAIR0. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" \n"
|
" \n"
|
||||||
" movs r3, #4 \n" /* r3 = 4. */
|
" movs r3, #4 \n" /* r3 = 4. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
" \n"
|
" \n"
|
||||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
" movs r3, #8 \n" /* r3 = 8. */
|
" movs r3, #8 \n" /* r3 = 8. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
" movs r3, #12 \n" /* r3 = 12. */
|
" movs r3, #12 \n" /* r3 = 12. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||||
" str r2, [r1] \n" /* Enable MPU. */
|
" str r2, [r1] \n" /* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n" /* Force memory writes before continuing. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_context: \n"
|
" restore_context: \n"
|
||||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||||
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_special_regs: \n"
|
" restore_special_regs: \n"
|
||||||
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||||
" msr psp, r3 \n"
|
" msr psp, r3 \n"
|
||||||
" msr psplim, r4 \n"
|
" msr psplim, r4 \n"
|
||||||
" msr control, r5 \n"
|
" msr control, r5 \n"
|
||||||
" ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
" ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
" str r0, [r4] \n" /* Restore xSecureContext. */
|
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||||
" cbz r0, restore_ns_context \n" /* No secure context to restore. */
|
" cbz r0, restore_ns_context \n" /* No secure context to restore. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_s_context: \n"
|
" restore_s_context: \n"
|
||||||
" push {r1-r3, lr} \n"
|
" push {r1-r3, lr} \n"
|
||||||
" bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
" bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||||
" pop {r1-r3, lr} \n"
|
" pop {r1-r3, lr} \n"
|
||||||
" \n"
|
" \n"
|
||||||
" restore_ns_context: \n"
|
" restore_ns_context: \n"
|
||||||
" mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
|
" mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
|
||||||
" lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
" lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
" bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
" bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_general_regs: \n"
|
" restore_general_regs: \n"
|
||||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||||
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||||
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
" tst lr, #0x10 \n"
|
" tst lr, #0x10 \n"
|
||||||
" ittt eq \n"
|
" ittt eq \n"
|
||||||
" vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
" vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||||
" vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
" vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||||
" vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */
|
" vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_context_done: \n"
|
" restore_context_done: \n"
|
||||||
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
" xSecureContextConst: .word xSecureContext \n"
|
" xSecureContextConst: .word xSecureContext \n"
|
||||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||||
" xRNRConst: .word 0xe000ed98 \n"
|
" xRNRConst: .word 0xe000ed98 \n"
|
||||||
" xRBARConst: .word 0xe000ed9c \n"
|
" xRBARConst: .word 0xe000ed9c \n"
|
||||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" .extern SecureContext_SaveContext \n"
|
" .extern SecureContext_SaveContext \n"
|
||||||
" .extern SecureContext_LoadContext \n"
|
" .extern SecureContext_LoadContext \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
" ldr r0, [r3] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||||
" mrs r2, psp \n"/* Read PSP in r2. */
|
" mrs r2, psp \n" /* Read PSP in r2. */
|
||||||
" \n"
|
" \n"
|
||||||
" cbz r0, save_ns_context \n"/* No secure context to save. */
|
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||||
" push {r0-r2, r14} \n"
|
" push {r0-r2, r14} \n"
|
||||||
" bl SecureContext_SaveContext \n"/* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||||
" pop {r0-r3} \n"/* LR is now in r3. */
|
" pop {r0-r3} \n" /* LR is now in r3. */
|
||||||
" mov lr, r3 \n"/* LR = r3. */
|
" mov lr, r3 \n" /* LR = r3. */
|
||||||
" lsls r1, r3, #25 \n"/* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
" lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
" bpl save_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
" bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB.*/
|
" ldr r1, [r3] \n" /* Read pxCurrentTCB.*/
|
||||||
" subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */
|
" subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */
|
||||||
" str r2, [r1] \n"/* Save the new top of stack in TCB. */
|
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
|
||||||
" mrs r1, psplim \n"/* r1 = PSPLIM. */
|
" mrs r1, psplim \n" /* r1 = PSPLIM. */
|
||||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||||
" stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
|
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||||
" b select_next_task \n"
|
" b select_next_task \n"
|
||||||
" \n"
|
" \n"
|
||||||
" save_ns_context: \n"
|
" save_ns_context: \n"
|
||||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB. */
|
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
|
||||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||||
" it eq \n"
|
" it eq \n"
|
||||||
" vstmdbeq r2!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */
|
" vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
" subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
|
" subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
|
||||||
" str r2, [r1] \n"/* Save the new top of stack in TCB. */
|
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
|
||||||
" adds r2, r2, #12 \n"/* r2 = r2 + 12. */
|
" adds r2, r2, #12 \n" /* r2 = r2 + 12. */
|
||||||
" stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */
|
" stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */
|
||||||
" mrs r1, psplim \n"/* r1 = PSPLIM. */
|
" mrs r1, psplim \n" /* r1 = PSPLIM. */
|
||||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||||
" subs r2, r2, #12 \n"/* r2 = r2 - 12. */
|
" subs r2, r2, #12 \n" /* r2 = r2 - 12. */
|
||||||
" stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
|
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||||
" \n"
|
" \n"
|
||||||
" select_next_task: \n"
|
" select_next_task: \n"
|
||||||
" mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
||||||
" msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
" msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" mov r0, #0 \n"/* r0 = 0. */
|
" mov r0, #0 \n" /* r0 = 0. */
|
||||||
" msr basepri, r0 \n"/* Enable interrupts. */
|
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB. */
|
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
|
||||||
" ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
|
" ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */
|
" ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */
|
||||||
" msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */
|
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */
|
||||||
" mov lr, r4 \n"/* LR = r4. */
|
" mov lr, r4 \n" /* LR = r4. */
|
||||||
" ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
" str r0, [r3] \n"/* Restore the task's xSecureContext. */
|
" str r0, [r3] \n" /* Restore the task's xSecureContext. */
|
||||||
" cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */
|
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
|
||||||
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r3] \n"/* Read pxCurrentTCB. */
|
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
|
||||||
" push {r2, r4} \n"
|
" push {r2, r4} \n"
|
||||||
" bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
" bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||||
" pop {r2, r4} \n"
|
" pop {r2, r4} \n"
|
||||||
" mov lr, r4 \n"/* LR = r4. */
|
" mov lr, r4 \n" /* LR = r4. */
|
||||||
" lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
" lsls r1, r4, #25 \n" /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
" bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
" bpl restore_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||||
" msr psp, r2 \n"/* Remember the new top of stack for the task. */
|
" msr psp, r2 \n" /* Remember the new top of stack for the task. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
" \n"
|
" \n"
|
||||||
" restore_ns_context: \n"
|
" restore_ns_context: \n"
|
||||||
" ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */
|
" ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */
|
||||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||||
" it eq \n"
|
" it eq \n"
|
||||||
" vldmiaeq r2!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */
|
" vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
" msr psp, r2 \n"/* Remember the new top of stack for the task. */
|
" msr psp, r2 \n" /* Remember the new top of stack for the task. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
"xSecureContextConst: .word xSecureContext \n"
|
"xSecureContextConst: .word xSecureContext \n"
|
||||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
".syntax unified \n"
|
".syntax unified \n"
|
||||||
".extern vPortSVCHandler_C \n"
|
".extern vPortSVCHandler_C \n"
|
||||||
".extern vSystemCallEnter \n"
|
".extern vSystemCallEnter \n"
|
||||||
".extern vSystemCallEnter_1 \n"
|
".extern vSystemCallEnter_1 \n"
|
||||||
".extern vSystemCallExit \n"
|
".extern vSystemCallExit \n"
|
||||||
" \n"
|
" \n"
|
||||||
"tst lr, #4 \n"
|
"tst lr, #4 \n"
|
||||||
"ite eq \n"
|
"ite eq \n"
|
||||||
"mrseq r0, msp \n"
|
"mrseq r0, msp \n"
|
||||||
"mrsne r0, psp \n"
|
"mrsne r0, psp \n"
|
||||||
" \n"
|
" \n"
|
||||||
"ldr r1, [r0, #24] \n"
|
"ldr r1, [r0, #24] \n"
|
||||||
"ldrb r2, [r1, #-2] \n"
|
"ldrb r2, [r1, #-2] \n"
|
||||||
"cmp r2, %0 \n"
|
"cmp r2, %0 \n"
|
||||||
"beq syscall_enter \n"
|
"beq syscall_enter \n"
|
||||||
"cmp r2, %1 \n"
|
"cmp r2, %1 \n"
|
||||||
"beq syscall_enter_1 \n"
|
"beq syscall_enter_1 \n"
|
||||||
"cmp r2, %2 \n"
|
"cmp r2, %2 \n"
|
||||||
"beq syscall_exit \n"
|
"beq syscall_exit \n"
|
||||||
"b vPortSVCHandler_C \n"
|
"b vPortSVCHandler_C \n"
|
||||||
" \n"
|
" \n"
|
||||||
"syscall_enter: \n"
|
"syscall_enter: \n"
|
||||||
" mov r1, lr \n"
|
" mov r1, lr \n"
|
||||||
" b vSystemCallEnter \n"
|
" b vSystemCallEnter \n"
|
||||||
" \n"
|
" \n"
|
||||||
"syscall_enter_1: \n"
|
"syscall_enter_1: \n"
|
||||||
" mov r1, lr \n"
|
" mov r1, lr \n"
|
||||||
" b vSystemCallEnter_1 \n"
|
" b vSystemCallEnter_1 \n"
|
||||||
" \n"
|
" \n"
|
||||||
"syscall_exit: \n"
|
"syscall_exit: \n"
|
||||||
" mov r1, lr \n"
|
" mov r1, lr \n"
|
||||||
" b vSystemCallExit \n"
|
" b vSystemCallExit \n"
|
||||||
" \n"
|
" \n"
|
||||||
: /* No outputs. */
|
: /* No outputs. */
|
||||||
:"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
: "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||||
: "r0", "r1", "r2", "memory"
|
: "r0", "r1", "r2", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" tst lr, #4 \n"
|
" tst lr, #4 \n"
|
||||||
" ite eq \n"
|
" ite eq \n"
|
||||||
" mrseq r0, msp \n"
|
" mrseq r0, msp \n"
|
||||||
" mrsne r0, psp \n"
|
" mrsne r0, psp \n"
|
||||||
" ldr r1, svchandler_address_const \n"
|
" ldr r1, svchandler_address_const \n"
|
||||||
" bx r1 \n"
|
" bx r1 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -587,8 +587,8 @@ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" svc %0 \n"/* Secure context is allocated in the supervisor call. */
|
" svc %0 \n" /* Secure context is allocated in the supervisor call. */
|
||||||
" bx lr \n"/* Return. */
|
" bx lr \n" /* Return. */
|
||||||
::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -600,12 +600,12 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, [r0] \n"/* The first item in the TCB is the top of the stack. */
|
" ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */
|
||||||
" ldr r1, [r2] \n"/* The first item on the stack is the task's xSecureContext. */
|
" ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */
|
||||||
" cmp r1, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */
|
" cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */
|
||||||
" it ne \n"
|
" it ne \n"
|
||||||
" svcne %0 \n"/* Secure context is freed in the supervisor call. */
|
" svcne %0 \n" /* Secure context is freed in the supervisor call. */
|
||||||
" bx lr \n"/* Return. */
|
" bx lr \n" /* Return. */
|
||||||
::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,9 +48,9 @@
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M33"
|
#define portARCH_NAME "Cortex-M33"
|
||||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ARMv8-M common port configurations. */
|
/* ARMv8-M common port configurations. */
|
||||||
|
@ -60,8 +60,8 @@
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -42,111 +42,111 @@
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" program_mpu_first_task: \n"
|
" program_mpu_first_task: \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||||
" str r2, [r1] \n" /* Disable MPU. */
|
" str r2, [r1] \n" /* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r1, [r2] \n" /* Program MAIR0. */
|
" str r1, [r2] \n" /* Program MAIR0. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" \n"
|
" \n"
|
||||||
" movs r3, #4 \n" /* r3 = 4. */
|
" movs r3, #4 \n" /* r3 = 4. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
" \n"
|
" \n"
|
||||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
" movs r3, #8 \n" /* r3 = 8. */
|
" movs r3, #8 \n" /* r3 = 8. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
" movs r3, #12 \n" /* r3 = 12. */
|
" movs r3, #12 \n" /* r3 = 12. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||||
" str r2, [r1] \n" /* Enable MPU. */
|
" str r2, [r1] \n" /* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n" /* Force memory writes before continuing. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_context_first_task: \n"
|
" restore_context_first_task: \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_special_regs_first_task: \n"
|
" restore_special_regs_first_task: \n"
|
||||||
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||||
" msr psp, r2 \n"
|
" msr psp, r2 \n"
|
||||||
" msr psplim, r3 \n"
|
" msr psplim, r3 \n"
|
||||||
" msr control, r4 \n"
|
" msr control, r4 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" restore_general_regs_first_task: \n"
|
" restore_general_regs_first_task: \n"
|
||||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||||
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_context_done_first_task: \n"
|
" restore_context_done_first_task: \n"
|
||||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||||
" mov r0, #0 \n"
|
" mov r0, #0 \n"
|
||||||
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||||
" xRNRConst2: .word 0xe000ed98 \n"
|
" xRNRConst2: .word 0xe000ed98 \n"
|
||||||
" xRBARConst2: .word 0xe000ed9c \n"
|
" xRBARConst2: .word 0xe000ed9c \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||||
" ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
" ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||||
" msr psplim, r1 \n"/* Set this task's PSPLIM value. */
|
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
||||||
" movs r1, #2 \n"/* r1 = 2. */
|
" movs r1, #2 \n" /* r1 = 2. */
|
||||||
" msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */
|
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||||
" adds r0, #32 \n"/* Discard everything up to r0. */
|
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" mov r0, #0 \n"
|
" mov r0, #0 \n"
|
||||||
" msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */
|
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||||
" bx r2 \n"/* Finally, branch to EXC_RETURN. */
|
" bx r2 \n" /* Finally, branch to EXC_RETURN. */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -157,12 +157,12 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
" tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||||
" ite ne \n"
|
" ite ne \n"
|
||||||
" movne r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
" movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||||
" moveq r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
" moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||||
" bx lr \n"/* Return. */
|
" bx lr \n" /* Return. */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
::: "r0", "memory"
|
::: "r0", "memory"
|
||||||
|
@ -176,10 +176,10 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, control \n"/* Read the CONTROL register. */
|
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||||
" bic r0, #1 \n"/* Clear the bit 0. */
|
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||||
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||||
" bx lr \n"/* Return to the caller. */
|
" bx lr \n" /* Return to the caller. */
|
||||||
::: "r0", "memory"
|
::: "r0", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -191,10 +191,10 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
" orr r0, #1 \n"/* r0 = r0 | 1. */
|
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||||
" msr control, r0 \n"/* CONTROL = r0. */
|
" msr control, r0 \n" /* CONTROL = r0. */
|
||||||
" bx lr \n"/* Return to the caller. */
|
" bx lr \n" /* Return to the caller. */
|
||||||
::: "r0", "memory"
|
::: "r0", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -206,15 +206,15 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
||||||
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
||||||
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
||||||
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||||
" cpsie i \n"/* Globally enable interrupts. */
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
" cpsie f \n"
|
" cpsie f \n"
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" svc %0 \n"/* System call to start the first task. */
|
" svc %0 \n" /* System call to start the first task. */
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
|
@ -230,12 +230,12 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */
|
" mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
|
||||||
" mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
" mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
" msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
" msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx lr \n"/* Return. */
|
" bx lr \n" /* Return. */
|
||||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -247,10 +247,10 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" msr basepri, r0 \n"/* basepri = ulMask. */
|
" msr basepri, r0 \n" /* basepri = ulMask. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx lr \n"/* Return. */
|
" bx lr \n" /* Return. */
|
||||||
::: "memory"
|
::: "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -258,246 +258,246 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||||
" ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */
|
" ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */
|
||||||
" mrs r2, psp \n" /* r2 = PSP. */
|
" mrs r2, psp \n" /* r2 = PSP. */
|
||||||
" \n"
|
" \n"
|
||||||
" save_general_regs: \n"
|
" save_general_regs: \n"
|
||||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
" add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */
|
" add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */
|
||||||
" tst lr, #0x10 \n"
|
" tst lr, #0x10 \n"
|
||||||
" ittt eq \n"
|
" ittt eq \n"
|
||||||
" vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */
|
" vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */
|
||||||
" vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
" vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||||
" vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */
|
" vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||||
" sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */
|
" sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
" \n"
|
" \n"
|
||||||
" stmia r1!, {r4-r11} \n" /* Store r4-r11. */
|
" stmia r1!, {r4-r11} \n" /* Store r4-r11. */
|
||||||
" ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
" ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||||
" stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */
|
" stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||||
" \n"
|
" \n"
|
||||||
" save_special_regs: \n"
|
" save_special_regs: \n"
|
||||||
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
||||||
" mrs r4, control \n" /* r4 = CONTROL. */
|
" mrs r4, control \n" /* r4 = CONTROL. */
|
||||||
" stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
" stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||||
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" select_next_task: \n"
|
" select_next_task: \n"
|
||||||
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
||||||
" msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
" msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" mov r0, #0 \n" /* r0 = 0. */
|
" mov r0, #0 \n" /* r0 = 0. */
|
||||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||||
" \n"
|
" \n"
|
||||||
" program_mpu: \n"
|
" program_mpu: \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||||
" str r2, [r1] \n" /* Disable MPU. */
|
" str r2, [r1] \n" /* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r1, [r2] \n" /* Program MAIR0. */
|
" str r1, [r2] \n" /* Program MAIR0. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" \n"
|
" \n"
|
||||||
" movs r3, #4 \n" /* r3 = 4. */
|
" movs r3, #4 \n" /* r3 = 4. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
" \n"
|
" \n"
|
||||||
#if ( configTOTAL_MPU_REGIONS == 16 )
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
" movs r3, #8 \n" /* r3 = 8. */
|
" movs r3, #8 \n" /* r3 = 8. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 8. */
|
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
" movs r3, #12 \n" /* r3 = 12. */
|
" movs r3, #12 \n" /* r3 = 12. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 12. */
|
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||||
" str r2, [r1] \n" /* Enable MPU. */
|
" str r2, [r1] \n" /* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n" /* Force memory writes before continuing. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_context: \n"
|
" restore_context: \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_special_regs: \n"
|
" restore_special_regs: \n"
|
||||||
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||||
" msr psp, r2 \n"
|
" msr psp, r2 \n"
|
||||||
" msr psplim, r3 \n"
|
" msr psplim, r3 \n"
|
||||||
" msr control, r4 \n"
|
" msr control, r4 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" restore_general_regs: \n"
|
" restore_general_regs: \n"
|
||||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||||
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||||
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
||||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
" tst lr, #0x10 \n"
|
" tst lr, #0x10 \n"
|
||||||
" ittt eq \n"
|
" ittt eq \n"
|
||||||
" vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
" vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||||
" vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
" vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||||
" vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */
|
" vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_context_done: \n"
|
" restore_context_done: \n"
|
||||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||||
" xRNRConst: .word 0xe000ed98 \n"
|
" xRNRConst: .word 0xe000ed98 \n"
|
||||||
" xRBARConst: .word 0xe000ed9c \n"
|
" xRBARConst: .word 0xe000ed9c \n"
|
||||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, psp \n"/* Read PSP in r0. */
|
" mrs r0, psp \n" /* Read PSP in r0. */
|
||||||
" \n"
|
" \n"
|
||||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||||
" it eq \n"
|
" it eq \n"
|
||||||
" vstmdbeq r0!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */
|
" vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||||
" stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
|
" stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||||
" str r0, [r1] \n"/* Save the new top of stack in TCB. */
|
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
||||||
" msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
" msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" mov r0, #0 \n"/* r0 = 0. */
|
" mov r0, #0 \n" /* r0 = 0. */
|
||||||
" msr basepri, r0 \n"/* Enable interrupts. */
|
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||||
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
|
" ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
|
||||||
" \n"
|
" \n"
|
||||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
" tst r3, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
" tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||||
" it eq \n"
|
" it eq \n"
|
||||||
" vldmiaeq r0!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */
|
" vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
" \n"
|
" \n"
|
||||||
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
|
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
||||||
" msr psp, r0 \n"/* Remember the new top of stack for the task. */
|
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
||||||
" bx r3 \n"
|
" bx r3 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
".syntax unified \n"
|
".syntax unified \n"
|
||||||
".extern vPortSVCHandler_C \n"
|
".extern vPortSVCHandler_C \n"
|
||||||
".extern vSystemCallEnter \n"
|
".extern vSystemCallEnter \n"
|
||||||
".extern vSystemCallEnter_1 \n"
|
".extern vSystemCallEnter_1 \n"
|
||||||
".extern vSystemCallExit \n"
|
".extern vSystemCallExit \n"
|
||||||
" \n"
|
" \n"
|
||||||
"tst lr, #4 \n"
|
"tst lr, #4 \n"
|
||||||
"ite eq \n"
|
"ite eq \n"
|
||||||
"mrseq r0, msp \n"
|
"mrseq r0, msp \n"
|
||||||
"mrsne r0, psp \n"
|
"mrsne r0, psp \n"
|
||||||
" \n"
|
" \n"
|
||||||
"ldr r1, [r0, #24] \n"
|
"ldr r1, [r0, #24] \n"
|
||||||
"ldrb r2, [r1, #-2] \n"
|
"ldrb r2, [r1, #-2] \n"
|
||||||
"cmp r2, %0 \n"
|
"cmp r2, %0 \n"
|
||||||
"beq syscall_enter \n"
|
"beq syscall_enter \n"
|
||||||
"cmp r2, %1 \n"
|
"cmp r2, %1 \n"
|
||||||
"beq syscall_enter_1 \n"
|
"beq syscall_enter_1 \n"
|
||||||
"cmp r2, %2 \n"
|
"cmp r2, %2 \n"
|
||||||
"beq syscall_exit \n"
|
"beq syscall_exit \n"
|
||||||
"b vPortSVCHandler_C \n"
|
"b vPortSVCHandler_C \n"
|
||||||
" \n"
|
" \n"
|
||||||
"syscall_enter: \n"
|
"syscall_enter: \n"
|
||||||
" mov r1, lr \n"
|
" mov r1, lr \n"
|
||||||
" b vSystemCallEnter \n"
|
" b vSystemCallEnter \n"
|
||||||
" \n"
|
" \n"
|
||||||
"syscall_enter_1: \n"
|
"syscall_enter_1: \n"
|
||||||
" mov r1, lr \n"
|
" mov r1, lr \n"
|
||||||
" b vSystemCallEnter_1 \n"
|
" b vSystemCallEnter_1 \n"
|
||||||
" \n"
|
" \n"
|
||||||
"syscall_exit: \n"
|
"syscall_exit: \n"
|
||||||
" mov r1, lr \n"
|
" mov r1, lr \n"
|
||||||
" b vSystemCallExit \n"
|
" b vSystemCallExit \n"
|
||||||
" \n"
|
" \n"
|
||||||
: /* No outputs. */
|
: /* No outputs. */
|
||||||
:"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
: "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||||
: "r0", "r1", "r2", "memory"
|
: "r0", "r1", "r2", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" tst lr, #4 \n"
|
" tst lr, #4 \n"
|
||||||
" ite eq \n"
|
" ite eq \n"
|
||||||
" mrseq r0, msp \n"
|
" mrseq r0, msp \n"
|
||||||
" mrsne r0, psp \n"
|
" mrsne r0, psp \n"
|
||||||
" ldr r1, svchandler_address_const \n"
|
" ldr r1, svchandler_address_const \n"
|
||||||
" bx r1 \n"
|
" bx r1 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
@ -48,9 +48,9 @@
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M33"
|
#define portARCH_NAME "Cortex-M33"
|
||||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ARMv8-M common port configurations. */
|
/* ARMv8-M common port configurations. */
|
||||||
|
@ -60,8 +60,8 @@
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
|
|
|
@ -48,9 +48,9 @@
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M35P"
|
#define portARCH_NAME "Cortex-M35P"
|
||||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ARMv8-M common port configurations. */
|
/* ARMv8-M common port configurations. */
|
||||||
|
@ -60,8 +60,8 @@
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
|
|
|
@ -53,9 +53,9 @@
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M55"
|
#define portARCH_NAME "Cortex-M55"
|
||||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ARMv8-M common port configurations. */
|
/* ARMv8-M common port configurations. */
|
||||||
|
@ -65,8 +65,8 @@
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
|
|
|
@ -53,9 +53,9 @@
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M85"
|
#define portARCH_NAME "Cortex-M85"
|
||||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ARMv8-M common port configurations. */
|
/* ARMv8-M common port configurations. */
|
||||||
|
@ -65,8 +65,8 @@
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
|
|
|
@ -48,9 +48,9 @@
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M23"
|
#define portARCH_NAME "Cortex-M23"
|
||||||
#define portHAS_ARMV8M_MAIN_EXTENSION 0
|
#define portHAS_ARMV8M_MAIN_EXTENSION 0
|
||||||
#define portDONT_DISCARD __root
|
#define portDONT_DISCARD __root
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ARMv8-M common port configurations. */
|
/* ARMv8-M common port configurations. */
|
||||||
|
|
|
@ -48,9 +48,9 @@
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M23"
|
#define portARCH_NAME "Cortex-M23"
|
||||||
#define portHAS_ARMV8M_MAIN_EXTENSION 0
|
#define portHAS_ARMV8M_MAIN_EXTENSION 0
|
||||||
#define portDONT_DISCARD __root
|
#define portDONT_DISCARD __root
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ARMv8-M common port configurations. */
|
/* ARMv8-M common port configurations. */
|
||||||
|
|
|
@ -48,12 +48,12 @@
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M33"
|
#define portARCH_NAME "Cortex-M33"
|
||||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
#define portDONT_DISCARD __root
|
#define portDONT_DISCARD __root
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configTOTAL_MPU_REGIONS == 16 )
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
#error 16 MPU regions are not yet supported for this port.
|
#error 16 MPU regions are not yet supported for this port.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -65,8 +65,8 @@
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
||||||
|
|
|
@ -48,16 +48,16 @@
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M33"
|
#define portARCH_NAME "Cortex-M33"
|
||||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
#define portDONT_DISCARD __root
|
#define portDONT_DISCARD __root
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ARMv8-M common port configurations. */
|
/* ARMv8-M common port configurations. */
|
||||||
#include "portmacrocommon.h"
|
#include "portmacrocommon.h"
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configTOTAL_MPU_REGIONS == 16 )
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
#error 16 MPU regions are not yet supported for this port.
|
#error 16 MPU regions are not yet supported for this port.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -65,8 +65,8 @@
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
||||||
|
|
|
@ -48,16 +48,16 @@
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M35P"
|
#define portARCH_NAME "Cortex-M35P"
|
||||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
#define portDONT_DISCARD __root
|
#define portDONT_DISCARD __root
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ARMv8-M common port configurations. */
|
/* ARMv8-M common port configurations. */
|
||||||
#include "portmacrocommon.h"
|
#include "portmacrocommon.h"
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configTOTAL_MPU_REGIONS == 16 )
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
#error 16 MPU regions are not yet supported for this port.
|
#error 16 MPU regions are not yet supported for this port.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -65,8 +65,8 @@
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
||||||
|
|
|
@ -53,16 +53,16 @@
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M55"
|
#define portARCH_NAME "Cortex-M55"
|
||||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
#define portDONT_DISCARD __root
|
#define portDONT_DISCARD __root
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ARMv8-M common port configurations. */
|
/* ARMv8-M common port configurations. */
|
||||||
#include "portmacrocommon.h"
|
#include "portmacrocommon.h"
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configTOTAL_MPU_REGIONS == 16 )
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
#error 16 MPU regions are not yet supported for this port.
|
#error 16 MPU regions are not yet supported for this port.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -70,8 +70,8 @@
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
||||||
|
|
|
@ -53,16 +53,16 @@
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M85"
|
#define portARCH_NAME "Cortex-M85"
|
||||||
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
#define portDONT_DISCARD __root
|
#define portDONT_DISCARD __root
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ARMv8-M common port configurations. */
|
/* ARMv8-M common port configurations. */
|
||||||
#include "portmacrocommon.h"
|
#include "portmacrocommon.h"
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configTOTAL_MPU_REGIONS == 16 )
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
#error 16 MPU regions are not yet supported for this port.
|
#error 16 MPU regions are not yet supported for this port.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -70,8 +70,8 @@
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
||||||
|
|
|
@ -81,8 +81,8 @@ typedef unsigned long UBaseType_t;
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 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. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#else
|
#else
|
||||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
|
@ -117,7 +117,7 @@ extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGE
|
||||||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
#if ( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
@ -188,13 +188,13 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Settings to define an MPU region.
|
* @brief Settings to define an MPU region.
|
||||||
*/
|
*/
|
||||||
typedef struct MPURegionSettings
|
typedef struct MPURegionSettings
|
||||||
{
|
{
|
||||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||||
} MPURegionSettings_t;
|
} MPURegionSettings_t;
|
||||||
|
|
||||||
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||||
|
@ -203,9 +203,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief System call stack.
|
* @brief System call stack.
|
||||||
*/
|
*/
|
||||||
typedef struct SYSTEM_CALL_STACK_INFO
|
typedef struct SYSTEM_CALL_STACK_INFO
|
||||||
{
|
{
|
||||||
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||||
|
@ -218,74 +218,74 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
|
|
||||||
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU settings as stored in the TCB.
|
* @brief MPU settings as stored in the TCB.
|
||||||
*/
|
*/
|
||||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||||
*
|
*
|
||||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||||
* 16 16 8 8 5 1
|
* 16 16 8 8 5 1
|
||||||
*/
|
*/
|
||||||
#define MAX_CONTEXT_SIZE 54
|
#define MAX_CONTEXT_SIZE 54
|
||||||
|
|
||||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||||
* | | | | PC, xPSR | EXC_RETURN | |
|
* | | | | PC, xPSR | EXC_RETURN | |
|
||||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||||
*
|
*
|
||||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||||
* 16 16 8 8 4 1
|
* 16 16 8 8 4 1
|
||||||
*/
|
*/
|
||||||
#define MAX_CONTEXT_SIZE 53
|
#define MAX_CONTEXT_SIZE 53
|
||||||
|
|
||||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||||
|
|
||||||
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* +----------+-----------------+------------------------------+-----+
|
* +----------+-----------------+------------------------------+-----+
|
||||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||||
* +----------+-----------------+------------------------------+-----+
|
* +----------+-----------------+------------------------------+-----+
|
||||||
*
|
*
|
||||||
* <---------><----------------><------------------------------><---->
|
* <---------><----------------><------------------------------><---->
|
||||||
* 8 8 5 1
|
* 8 8 5 1
|
||||||
*/
|
*/
|
||||||
#define MAX_CONTEXT_SIZE 22
|
#define MAX_CONTEXT_SIZE 22
|
||||||
|
|
||||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* +----------+-----------------+----------------------+-----+
|
* +----------+-----------------+----------------------+-----+
|
||||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||||
* | | PC, xPSR | EXC_RETURN | |
|
* | | PC, xPSR | EXC_RETURN | |
|
||||||
* +----------+-----------------+----------------------+-----+
|
* +----------+-----------------+----------------------+-----+
|
||||||
*
|
*
|
||||||
* <---------><----------------><----------------------><---->
|
* <---------><----------------><----------------------><---->
|
||||||
* 8 8 4 1
|
* 8 8 4 1
|
||||||
*/
|
*/
|
||||||
#define MAX_CONTEXT_SIZE 21
|
#define MAX_CONTEXT_SIZE 21
|
||||||
|
|
||||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||||
|
|
||||||
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||||
|
|
||||||
typedef struct MPU_SETTINGS
|
typedef struct MPU_SETTINGS
|
||||||
{
|
{
|
||||||
|
@ -364,49 +364,49 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
|
|
||||||
#if ( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allocate a secure context for the task.
|
* @brief Allocate a secure context for the task.
|
||||||
*
|
*
|
||||||
* Tasks are not created with a secure context. Any task that is going to call
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||||
* secure context before it calls any secure function.
|
* secure context before it calls any secure function.
|
||||||
*
|
*
|
||||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||||
*/
|
*/
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when a task is deleted to delete the task's secure context,
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
* if it has one.
|
* if it has one.
|
||||||
*
|
*
|
||||||
* @param[in] pxTCB The TCB of the task being deleted.
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
*/
|
*/
|
||||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the processor is privileged.
|
* @brief Checks whether or not the processor is privileged.
|
||||||
*
|
*
|
||||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raise an SVC request to raise privilege.
|
* @brief Raise an SVC request to raise privilege.
|
||||||
*
|
*
|
||||||
* The SVC handler checks that the SVC was raised from a system call and only
|
* The SVC handler checks that the SVC was raised from a system call and only
|
||||||
* then it raises the privilege. If this is called from any other place,
|
* then it raises the privilege. If this is called from any other place,
|
||||||
* the privilege is not raised.
|
* the privilege is not raised.
|
||||||
*/
|
*/
|
||||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
* register.
|
* register.
|
||||||
*/
|
*/
|
||||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||||
#else
|
#else
|
||||||
#define portIS_PRIVILEGED()
|
#define portIS_PRIVILEGED()
|
||||||
|
@ -419,12 +419,12 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
|
|
||||||
extern BaseType_t xPortIsTaskPrivileged( void );
|
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the calling task is privileged.
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
*
|
*
|
||||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
*/
|
*/
|
||||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||||
|
|
||||||
#endif /* configENABLE_MPU == 1 */
|
#endif /* configENABLE_MPU == 1 */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -439,9 +439,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
* based on whether or not Mainline extension is implemented. */
|
* based on whether or not Mainline extension is implemented. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#else
|
#else
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
#endif
|
#endif
|
||||||
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
@ -450,9 +450,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
*/
|
*/
|
||||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Count the number of leading zeros in a 32-bit value.
|
* @brief Count the number of leading zeros in a 32-bit value.
|
||||||
*/
|
*/
|
||||||
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
{
|
{
|
||||||
uint32_t ulReturn;
|
uint32_t ulReturn;
|
||||||
|
@ -462,7 +462,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
return ulReturn;
|
return ulReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if ( configMAX_PRIORITIES > 32 )
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
|
@ -471,16 +471,16 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Store/clear the ready priorities in a bit map.
|
* @brief Store/clear the ready priorities in a bit map.
|
||||||
*/
|
*/
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||||
*/
|
*/
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
* @brief Maximum number of secure contexts.
|
* @brief Maximum number of secure contexts.
|
||||||
*/
|
*/
|
||||||
#ifndef secureconfigMAX_SECURE_CONTEXTS
|
#ifndef secureconfigMAX_SECURE_CONTEXTS
|
||||||
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -164,15 +164,15 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
/* Configure thread mode to use PSP and to be unprivileged. */
|
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||||
}
|
}
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
{
|
{
|
||||||
/* Configure thread mode to use PSP and to be privileged. */
|
/* Configure thread mode to use PSP and to be privileged. */
|
||||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,16 +219,16 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
if( pucStackMemory != NULL )
|
if( pucStackMemory != NULL )
|
||||||
{
|
{
|
||||||
/* Since stack grows down, the starting point will be the last
|
/* Since stack grows down, the starting point will be the last
|
||||||
* location. Note that this location is next to the last
|
* location. Note that this location is next to the last
|
||||||
* allocated byte for stack (excluding the space for seal values)
|
* allocated byte for stack (excluding the space for seal values)
|
||||||
* because the hardware decrements the stack pointer before
|
* because the hardware decrements the stack pointer before
|
||||||
* writing i.e. if stack pointer is 0x2, a push operation will
|
* writing i.e. if stack pointer is 0x2, a push operation will
|
||||||
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
||||||
xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
|
xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
|
||||||
|
|
||||||
/* Seal the created secure process stack. */
|
/* Seal the created secure process stack. */
|
||||||
*( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
||||||
*( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
||||||
|
|
||||||
/* The stack cannot go beyond this location. This value is
|
/* The stack cannot go beyond this location. This value is
|
||||||
* programmed in the PSPLIM register on context switch.*/
|
* programmed in the PSPLIM register on context switch.*/
|
||||||
|
@ -237,32 +237,32 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle;
|
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
{
|
||||||
|
/* Store the correct CONTROL value for the task on the stack.
|
||||||
|
* This value is programmed in the CONTROL register on
|
||||||
|
* context switch. */
|
||||||
|
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||||
|
pulCurrentStackPointer--;
|
||||||
|
|
||||||
|
if( ulIsTaskPrivileged )
|
||||||
{
|
{
|
||||||
/* Store the correct CONTROL value for the task on the stack.
|
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||||
* This value is programmed in the CONTROL register on
|
|
||||||
* context switch. */
|
|
||||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
|
||||||
pulCurrentStackPointer--;
|
|
||||||
|
|
||||||
if( ulIsTaskPrivileged )
|
|
||||||
{
|
|
||||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store the current stack pointer. This value is programmed in
|
|
||||||
* the PSP register on context switch. */
|
|
||||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the current stack pointer. This value is programmed in
|
||||||
|
* the PSP register on context switch. */
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||||
|
}
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
{
|
{
|
||||||
/* Current SP is set to the starting of the stack. This
|
/* Current SP is set to the starting of the stack. This
|
||||||
* value programmed in the PSP register on context switch. */
|
* value programmed in the PSP register on context switch. */
|
||||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
/* Ensure to never return 0 as a valid context handle. */
|
/* Ensure to never return 0 as a valid context handle. */
|
||||||
|
@ -275,7 +275,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
{
|
{
|
||||||
uint32_t ulIPSR, ulSecureContextIndex;
|
uint32_t ulIPSR, ulSecureContextIndex;
|
||||||
|
|
||||||
|
@ -306,7 +307,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
{
|
{
|
||||||
uint8_t * pucStackLimit;
|
uint8_t * pucStackLimit;
|
||||||
uint32_t ulSecureContextIndex;
|
uint32_t ulSecureContextIndex;
|
||||||
|
@ -328,7 +330,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandl
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
{
|
{
|
||||||
uint8_t * pucStackLimit;
|
uint8_t * pucStackLimit;
|
||||||
uint32_t ulSecureContextIndex;
|
uint32_t ulSecureContextIndex;
|
||||||
|
|
|
@ -38,12 +38,12 @@
|
||||||
/**
|
/**
|
||||||
* @brief PSP value when no secure context is loaded.
|
* @brief PSP value when no secure context is loaded.
|
||||||
*/
|
*/
|
||||||
#define securecontextNO_STACK 0x0
|
#define securecontextNO_STACK 0x0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Invalid context ID.
|
* @brief Invalid context ID.
|
||||||
*/
|
*/
|
||||||
#define securecontextINVALID_CONTEXT_ID 0UL
|
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -108,7 +108,8 @@ void SecureContext_Init( void );
|
||||||
* @param[in] xSecureContextHandle Context handle corresponding to the
|
* @param[in] xSecureContextHandle Context handle corresponding to the
|
||||||
* context to be freed.
|
* context to be freed.
|
||||||
*/
|
*/
|
||||||
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Loads the given context.
|
* @brief Loads the given context.
|
||||||
|
@ -119,7 +120,8 @@ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void
|
||||||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||||
* to be loaded.
|
* to be loaded.
|
||||||
*/
|
*/
|
||||||
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Saves the given context.
|
* @brief Saves the given context.
|
||||||
|
@ -130,6 +132,7 @@ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void
|
||||||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||||
* to be saved.
|
* to be saved.
|
||||||
*/
|
*/
|
||||||
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
#endif /* __SECURE_CONTEXT_H__ */
|
#endif /* __SECURE_CONTEXT_H__ */
|
||||||
|
|
|
@ -67,7 +67,7 @@
|
||||||
#define secureheapSIZE_MAX ( ~( ( size_t ) 0 ) )
|
#define secureheapSIZE_MAX ( ~( ( size_t ) 0 ) )
|
||||||
|
|
||||||
/* Check if adding a and b will result in overflow. */
|
/* Check if adding a and b will result in overflow. */
|
||||||
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
||||||
|
|
||||||
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
|
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
|
||||||
* the allocation status of a block. When MSB of the xBlockSize member of
|
* the allocation status of a block. When MSB of the xBlockSize member of
|
||||||
|
@ -397,17 +397,17 @@ void * pvPortMalloc( size_t xWantedSize )
|
||||||
traceMALLOC( pvReturn, xWantedSize );
|
traceMALLOC( pvReturn, xWantedSize );
|
||||||
|
|
||||||
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
||||||
|
{
|
||||||
|
if( pvReturn == NULL )
|
||||||
{
|
{
|
||||||
if( pvReturn == NULL )
|
extern void vApplicationMallocFailedHook( void );
|
||||||
{
|
vApplicationMallocFailedHook();
|
||||||
extern void vApplicationMallocFailedHook( void );
|
|
||||||
vApplicationMallocFailedHook();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mtCOVERAGE_TEST_MARKER();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||||
|
|
||||||
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||||
|
|
|
@ -93,7 +93,7 @@ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void )
|
||||||
* permitted. CP11 should be programmed to the same value as CP10. */
|
* permitted. CP11 should be programmed to the same value as CP10. */
|
||||||
*( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK );
|
*( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK );
|
||||||
|
|
||||||
/* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures
|
/* LSPENS = 0 ==> LSPEN is writable from non-secure state. This ensures
|
||||||
* that we can enable/disable lazy stacking in port.c file. */
|
* that we can enable/disable lazy stacking in port.c file. */
|
||||||
*( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK );
|
*( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK );
|
||||||
|
|
||||||
|
|
|
@ -27,22 +27,22 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V1.00:
|
* Changes from V1.00:
|
||||||
|
*
|
||||||
+ Call to taskYIELD() from within tick ISR has been replaced by the more
|
+ Call to taskYIELD() from within tick ISR has been replaced by the more
|
||||||
efficient portSWITCH_CONTEXT().
|
+ efficient portSWITCH_CONTEXT().
|
||||||
+ ISR function definitions renamed to include the prv prefix.
|
+ ISR function definitions renamed to include the prv prefix.
|
||||||
|
+
|
||||||
Changes from V2.6.1
|
+ Changes from V2.6.1
|
||||||
|
+
|
||||||
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
||||||
macro to be consistent with the later ports.
|
+ macro to be consistent with the later ports.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the Flashlite 186
|
* Implementation of functions defined in portable.h for the Flashlite 186
|
||||||
* port.
|
* port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -54,9 +54,9 @@ Changes from V2.6.1
|
||||||
|
|
||||||
/*lint -e950 Non ANSI reserved words okay in this file only. */
|
/*lint -e950 Non ANSI reserved words okay in this file only. */
|
||||||
|
|
||||||
#define portTIMER_EOI_TYPE ( 8 )
|
#define portTIMER_EOI_TYPE ( 8 )
|
||||||
#define portRESET_PIC() portOUTPUT_WORD( ( uint16_t ) 0xff22, portTIMER_EOI_TYPE )
|
#define portRESET_PIC() portOUTPUT_WORD( ( uint16_t ) 0xff22, portTIMER_EOI_TYPE )
|
||||||
#define portTIMER_INT_NUMBER 0x12
|
#define portTIMER_INT_NUMBER 0x12
|
||||||
|
|
||||||
#define portTIMER_1_CONTROL_REGISTER ( ( uint16_t ) 0xff5e )
|
#define portTIMER_1_CONTROL_REGISTER ( ( uint16_t ) 0xff5e )
|
||||||
#define portTIMER_0_CONTROL_REGISTER ( ( uint16_t ) 0xff56 )
|
#define portTIMER_0_CONTROL_REGISTER ( ( uint16_t ) 0xff56 )
|
||||||
|
@ -69,14 +69,16 @@ static void prvSetTickFrequency( uint32_t ulTickRateHz );
|
||||||
static void prvExitFunction( void );
|
static void prvExitFunction( void );
|
||||||
|
|
||||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||||
is being used. */
|
* is being used. */
|
||||||
#if( configUSE_PREEMPTION == 1 )
|
#if ( configUSE_PREEMPTION == 1 )
|
||||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
|
||||||
being used. */
|
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||||
|
* being used. */
|
||||||
static void __interrupt __far prvPreemptiveTick( void );
|
static void __interrupt __far prvPreemptiveTick( void );
|
||||||
#else
|
#else
|
||||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
|
||||||
being used. */
|
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||||
|
* being used. */
|
||||||
static void __interrupt __far prvNonPreemptiveTick( void );
|
static void __interrupt __far prvNonPreemptiveTick( void );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -89,9 +91,9 @@ static void __interrupt __far prvYieldProcessor( void );
|
||||||
static BaseType_t xSchedulerRunning = pdFALSE;
|
static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
||||||
/* Points to the original routine installed on the vector we use for manual
|
/* Points to the original routine installed on the vector we use for manual
|
||||||
context switches. This is then used to restore the original routine during
|
* context switches. This is then used to restore the original routine during
|
||||||
prvExitFunction(). */
|
* prvExitFunction(). */
|
||||||
static void ( __interrupt __far *pxOldSwitchISR )();
|
static void( __interrupt __far * pxOldSwitchISR )();
|
||||||
|
|
||||||
/* Used to restore the original DOS context when the scheduler is ended. */
|
/* Used to restore the original DOS context when the scheduler is ended. */
|
||||||
static jmp_buf xJumpBuf;
|
static jmp_buf xJumpBuf;
|
||||||
|
@ -104,14 +106,14 @@ BaseType_t xPortStartScheduler( void )
|
||||||
/* This is called with interrupts already disabled. */
|
/* This is called with interrupts already disabled. */
|
||||||
|
|
||||||
/* Remember what was on the interrupts we are going to use
|
/* Remember what was on the interrupts we are going to use
|
||||||
so we can put them back later if required. */
|
* so we can put them back later if required. */
|
||||||
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
||||||
|
|
||||||
/* Put our manual switch (yield) function on a known
|
/* Put our manual switch (yield) function on a known
|
||||||
vector. */
|
* vector. */
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
||||||
|
|
||||||
#if( configUSE_PREEMPTION == 1 )
|
#if ( configUSE_PREEMPTION == 1 )
|
||||||
{
|
{
|
||||||
/* Put our tick switch function on the timer interrupt. */
|
/* Put our tick switch function on the timer interrupt. */
|
||||||
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
||||||
|
@ -144,8 +146,8 @@ BaseType_t xPortStartScheduler( void )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||||
is being used. */
|
* is being used. */
|
||||||
#if( configUSE_PREEMPTION == 1 )
|
#if ( configUSE_PREEMPTION == 1 )
|
||||||
static void __interrupt __far prvPreemptiveTick( void )
|
static void __interrupt __far prvPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Get the scheduler to update the task states following the tick. */
|
/* Get the scheduler to update the task states following the tick. */
|
||||||
|
@ -158,15 +160,15 @@ is being used. */
|
||||||
/* Reset the PIC ready for the next time. */
|
/* Reset the PIC ready for the next time. */
|
||||||
portRESET_PIC();
|
portRESET_PIC();
|
||||||
}
|
}
|
||||||
#else
|
#else /* if ( configUSE_PREEMPTION == 1 ) */
|
||||||
static void __interrupt __far prvNonPreemptiveTick( void )
|
static void __interrupt __far prvNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Same as preemptive tick, but the cooperative scheduler is being used
|
/* Same as preemptive tick, but the cooperative scheduler is being used
|
||||||
so we don't have to switch in the context of the next task. */
|
* so we don't have to switch in the context of the next task. */
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
portRESET_PIC();
|
portRESET_PIC();
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* if ( configUSE_PREEMPTION == 1 ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void __interrupt __far prvYieldProcessor( void )
|
static void __interrupt __far prvYieldProcessor( void )
|
||||||
|
@ -179,30 +181,31 @@ static void __interrupt __far prvYieldProcessor( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Jump back to the processor state prior to starting the
|
/* Jump back to the processor state prior to starting the
|
||||||
scheduler. This means we are not going to be using a
|
* scheduler. This means we are not going to be using a
|
||||||
task stack frame so the task can be deleted. */
|
* task stack frame so the task can be deleted. */
|
||||||
longjmp( xJumpBuf, 1 );
|
longjmp( xJumpBuf, 1 );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvExitFunction( void )
|
static void prvExitFunction( void )
|
||||||
{
|
{
|
||||||
const uint16_t usTimerDisable = 0x0000;
|
const uint16_t usTimerDisable = 0x0000;
|
||||||
uint16_t usTimer0Control;
|
uint16_t usTimer0Control;
|
||||||
|
|
||||||
/* Interrupts should be disabled here anyway - but no
|
/* Interrupts should be disabled here anyway - but no
|
||||||
harm in making sure. */
|
* harm in making sure. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if( xSchedulerRunning == pdTRUE )
|
if( xSchedulerRunning == pdTRUE )
|
||||||
{
|
{
|
||||||
/* Put back the switch interrupt routines that was in place
|
/* Put back the switch interrupt routines that was in place
|
||||||
before the scheduler started. */
|
* before the scheduler started. */
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable the timer used for the tick to ensure the scheduler is
|
/* Disable the timer used for the tick to ensure the scheduler is
|
||||||
not called before restoring interrupts. There was previously nothing
|
* not called before restoring interrupts. There was previously nothing
|
||||||
on this timer so there is no old ISR to restore. */
|
* on this timer so there is no old ISR to restore. */
|
||||||
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerDisable );
|
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerDisable );
|
||||||
|
|
||||||
/* Restart the DOS tick. */
|
/* Restart the DOS tick. */
|
||||||
|
@ -217,18 +220,18 @@ uint16_t usTimer0Control;
|
||||||
|
|
||||||
static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
||||||
{
|
{
|
||||||
const uint16_t usMaxCountRegister = 0xff5a;
|
const uint16_t usMaxCountRegister = 0xff5a;
|
||||||
const uint16_t usTimerPriorityRegister = 0xff32;
|
const uint16_t usTimerPriorityRegister = 0xff32;
|
||||||
const uint16_t usTimerEnable = 0xC000;
|
const uint16_t usTimerEnable = 0xC000;
|
||||||
const uint16_t usRetrigger = 0x0001;
|
const uint16_t usRetrigger = 0x0001;
|
||||||
const uint16_t usTimerHighPriority = 0x0000;
|
const uint16_t usTimerHighPriority = 0x0000;
|
||||||
uint16_t usTimer0Control;
|
uint16_t usTimer0Control;
|
||||||
|
|
||||||
/* ( CPU frequency / 4 ) / clock 2 max count [inpw( 0xff62 ) = 7] */
|
/* ( CPU frequency / 4 ) / clock 2 max count [inpw( 0xff62 ) = 7] */
|
||||||
|
|
||||||
const uint32_t ulClockFrequency = ( uint32_t ) 0x7f31a0UL;
|
const uint32_t ulClockFrequency = ( uint32_t ) 0x7f31a0UL;
|
||||||
|
|
||||||
uint32_t ulTimerCount = ulClockFrequency / ulTickRateHz;
|
uint32_t ulTimerCount = ulClockFrequency / ulTickRateHz;
|
||||||
|
|
||||||
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerEnable | portTIMER_INTERRUPT_ENABLE | usRetrigger );
|
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerEnable | portTIMER_INTERRUPT_ENABLE | usRetrigger );
|
||||||
portOUTPUT_WORD( usMaxCountRegister, ( uint16_t ) ulTimerCount );
|
portOUTPUT_WORD( usMaxCountRegister, ( uint16_t ) ulTimerCount );
|
||||||
|
|
|
@ -40,60 +40,61 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE long
|
#define portDOUBLE long
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT int
|
#define portSHORT int
|
||||||
#define portSTACK_TYPE uint16_t
|
#define portSTACK_TYPE uint16_t
|
||||||
#define portBASE_TYPE portSHORT
|
#define portBASE_TYPE portSHORT
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef short BaseType_t;
|
typedef short BaseType_t;
|
||||||
typedef unsigned short UBaseType_t;
|
typedef unsigned short UBaseType_t;
|
||||||
|
|
||||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#else
|
#else
|
||||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section handling. */
|
/* Critical section handling. */
|
||||||
#define portENTER_CRITICAL() __asm{ pushf } \
|
#define portENTER_CRITICAL() \
|
||||||
__asm{ cli } \
|
__asm { pushf } \
|
||||||
|
__asm { cli } \
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() __asm{ popf }
|
#define portEXIT_CRITICAL() __asm { popf }
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() __asm{ cli }
|
#define portDISABLE_INTERRUPTS() __asm { cli }
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() __asm{ sti }
|
#define portENABLE_INTERRUPTS() __asm { sti }
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portNOP() __asm{ nop }
|
#define portNOP() __asm { nop }
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portSWITCH_INT_NUMBER 0x80
|
#define portSWITCH_INT_NUMBER 0x80
|
||||||
#define portYIELD() __asm{ int portSWITCH_INT_NUMBER }
|
#define portYIELD() __asm { int portSWITCH_INT_NUMBER }
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 2
|
#define portBYTE_ALIGNMENT 2
|
||||||
#define portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */
|
#define portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Compiler specifics. */
|
/* Compiler specifics. */
|
||||||
#define portINPUT_BYTE( xAddr ) inp( xAddr )
|
#define portINPUT_BYTE( xAddr ) inp( xAddr )
|
||||||
#define portOUTPUT_BYTE( xAddr, ucValue ) outp( xAddr, ucValue )
|
#define portOUTPUT_BYTE( xAddr, ucValue ) outp( xAddr, ucValue )
|
||||||
#define portINPUT_WORD( xAddr ) inpw( xAddr )
|
#define portINPUT_WORD( xAddr ) inpw( xAddr )
|
||||||
#define portOUTPUT_WORD( xAddr, usValue ) outpw( xAddr, usValue )
|
#define portOUTPUT_WORD( xAddr, usValue ) outpw( xAddr, usValue )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vTaskFunction, vParameters ) void vTaskFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void * pvParameters )
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
@ -27,16 +27,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V2.6.1
|
* Changes from V2.6.1
|
||||||
|
*
|
||||||
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
||||||
macro to be consistent with the later ports.
|
+ macro to be consistent with the later ports.
|
||||||
|
+
|
||||||
Changes from V4.0.1
|
+ Changes from V4.0.1
|
||||||
|
+
|
||||||
+ Add function prvSetTickFrequencyDefault() to set the DOS tick back to
|
+ Add function prvSetTickFrequencyDefault() to set the DOS tick back to
|
||||||
its proper value when the scheduler exits.
|
+ its proper value when the scheduler exits.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
|
@ -47,9 +47,9 @@ Changes from V4.0.1
|
||||||
#include "portasm.h"
|
#include "portasm.h"
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the industrial
|
* Implementation of functions defined in portable.h for the industrial
|
||||||
* PC port.
|
* PC port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/*lint -e950 Non ANSI reserved words okay in this file only. */
|
/*lint -e950 Non ANSI reserved words okay in this file only. */
|
||||||
|
|
||||||
|
@ -62,19 +62,21 @@ static void prvSetTickFrequency( uint32_t ulTickRateHz );
|
||||||
static void prvExitFunction( void );
|
static void prvExitFunction( void );
|
||||||
|
|
||||||
/* Either chain to the DOS tick (which itself clears the PIC) or clear the PIC
|
/* Either chain to the DOS tick (which itself clears the PIC) or clear the PIC
|
||||||
directly. We chain to the DOS tick as close as possible to the standard DOS
|
* directly. We chain to the DOS tick as close as possible to the standard DOS
|
||||||
tick rate. */
|
* tick rate. */
|
||||||
static void prvPortResetPIC( void );
|
static void prvPortResetPIC( void );
|
||||||
|
|
||||||
/* The ISR used depends on whether the preemptive or cooperative
|
/* The ISR used depends on whether the preemptive or cooperative
|
||||||
scheduler is being used. */
|
* scheduler is being used. */
|
||||||
#if( configUSE_PREEMPTION == 1 )
|
#if ( configUSE_PREEMPTION == 1 )
|
||||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
|
||||||
being used. */
|
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||||
|
* being used. */
|
||||||
static void __interrupt __far prvPreemptiveTick( void );
|
static void __interrupt __far prvPreemptiveTick( void );
|
||||||
#else
|
#else
|
||||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
|
||||||
being used. */
|
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||||
|
* being used. */
|
||||||
static void __interrupt __far prvNonPreemptiveTick( void );
|
static void __interrupt __far prvNonPreemptiveTick( void );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -82,7 +84,7 @@ scheduler is being used. */
|
||||||
static void __interrupt __far prvYieldProcessor( void );
|
static void __interrupt __far prvYieldProcessor( void );
|
||||||
|
|
||||||
/* Set the tick frequency back so the floppy drive works correctly when the
|
/* Set the tick frequency back so the floppy drive works correctly when the
|
||||||
scheduler exits. */
|
* scheduler exits. */
|
||||||
static void prvSetTickFrequencyDefault( void );
|
static void prvSetTickFrequencyDefault( void );
|
||||||
|
|
||||||
/*lint -e956 File scopes necessary here. */
|
/*lint -e956 File scopes necessary here. */
|
||||||
|
@ -94,10 +96,10 @@ static int16_t sDOSTickCounter;
|
||||||
static BaseType_t xSchedulerRunning = pdFALSE;
|
static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
||||||
/* Points to the original routine installed on the vector we use for manual context switches. This is then used to restore the original routine during prvExitFunction(). */
|
/* Points to the original routine installed on the vector we use for manual context switches. This is then used to restore the original routine during prvExitFunction(). */
|
||||||
static void ( __interrupt __far *pxOldSwitchISR )();
|
static void( __interrupt __far * pxOldSwitchISR )();
|
||||||
|
|
||||||
/* Points to the original routine installed on the vector we use to chain to the DOS tick. This is then used to restore the original routine during prvExitFunction(). */
|
/* Points to the original routine installed on the vector we use to chain to the DOS tick. This is then used to restore the original routine during prvExitFunction(). */
|
||||||
static void ( __interrupt __far *pxOldSwitchISRPlus1 )();
|
static void( __interrupt __far * pxOldSwitchISRPlus1 )();
|
||||||
|
|
||||||
/* Used to restore the original DOS context when the scheduler is ended. */
|
/* Used to restore the original DOS context when the scheduler is ended. */
|
||||||
static jmp_buf xJumpBuf;
|
static jmp_buf xJumpBuf;
|
||||||
|
@ -107,12 +109,12 @@ static jmp_buf xJumpBuf;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
pxISR pxOriginalTickISR;
|
pxISR pxOriginalTickISR;
|
||||||
|
|
||||||
/* This is called with interrupts already disabled. */
|
/* This is called with interrupts already disabled. */
|
||||||
|
|
||||||
/* Remember what was on the interrupts we are going to use
|
/* Remember what was on the interrupts we are going to use
|
||||||
so we can put them back later if required. */
|
* so we can put them back later if required. */
|
||||||
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
||||||
pxOriginalTickISR = _dos_getvect( portTIMER_INT_NUMBER );
|
pxOriginalTickISR = _dos_getvect( portTIMER_INT_NUMBER );
|
||||||
pxOldSwitchISRPlus1 = _dos_getvect( portSWITCH_INT_NUMBER + 1 );
|
pxOldSwitchISRPlus1 = _dos_getvect( portSWITCH_INT_NUMBER + 1 );
|
||||||
|
@ -120,16 +122,16 @@ pxISR pxOriginalTickISR;
|
||||||
prvSetTickFrequency( configTICK_RATE_HZ );
|
prvSetTickFrequency( configTICK_RATE_HZ );
|
||||||
|
|
||||||
/* Put our manual switch (yield) function on a known
|
/* Put our manual switch (yield) function on a known
|
||||||
vector. */
|
* vector. */
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
||||||
|
|
||||||
/* Put the old tick on a different interrupt number so we can
|
/* Put the old tick on a different interrupt number so we can
|
||||||
call it when we want. */
|
* call it when we want. */
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOriginalTickISR );
|
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOriginalTickISR );
|
||||||
|
|
||||||
/* The ISR used depends on whether the preemptive or cooperative
|
/* The ISR used depends on whether the preemptive or cooperative
|
||||||
scheduler is being used. */
|
* scheduler is being used. */
|
||||||
#if( configUSE_PREEMPTION == 1 )
|
#if ( configUSE_PREEMPTION == 1 )
|
||||||
{
|
{
|
||||||
/* Put our tick switch function on the timer interrupt. */
|
/* Put our tick switch function on the timer interrupt. */
|
||||||
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
||||||
|
@ -142,8 +144,8 @@ pxISR pxOriginalTickISR;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Setup a counter that is used to call the DOS interrupt as close
|
/* Setup a counter that is used to call the DOS interrupt as close
|
||||||
to it's original frequency as can be achieved given our chosen tick
|
* to it's original frequency as can be achieved given our chosen tick
|
||||||
frequency. */
|
* frequency. */
|
||||||
sDOSTickCounter = portTICKS_PER_DOS_TICK;
|
sDOSTickCounter = portTICKS_PER_DOS_TICK;
|
||||||
|
|
||||||
/* Clean up function if we want to return to DOS. */
|
/* Clean up function if we want to return to DOS. */
|
||||||
|
@ -165,8 +167,8 @@ pxISR pxOriginalTickISR;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* The ISR used depends on whether the preemptive or cooperative
|
/* The ISR used depends on whether the preemptive or cooperative
|
||||||
scheduler is being used. */
|
* scheduler is being used. */
|
||||||
#if( configUSE_PREEMPTION == 1 )
|
#if ( configUSE_PREEMPTION == 1 )
|
||||||
static void __interrupt __far prvPreemptiveTick( void )
|
static void __interrupt __far prvPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Get the scheduler to update the task states following the tick. */
|
/* Get the scheduler to update the task states following the tick. */
|
||||||
|
@ -179,15 +181,15 @@ scheduler is being used. */
|
||||||
/* Reset the PIC ready for the next time. */
|
/* Reset the PIC ready for the next time. */
|
||||||
prvPortResetPIC();
|
prvPortResetPIC();
|
||||||
}
|
}
|
||||||
#else
|
#else /* if ( configUSE_PREEMPTION == 1 ) */
|
||||||
static void __interrupt __far prvNonPreemptiveTick( void )
|
static void __interrupt __far prvNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Same as preemptive tick, but the cooperative scheduler is being used
|
/* Same as preemptive tick, but the cooperative scheduler is being used
|
||||||
so we don't have to switch in the context of the next task. */
|
* so we don't have to switch in the context of the next task. */
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
prvPortResetPIC();
|
prvPortResetPIC();
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* if ( configUSE_PREEMPTION == 1 ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void __interrupt __far prvYieldProcessor( void )
|
static void __interrupt __far prvYieldProcessor( void )
|
||||||
|
@ -200,19 +202,22 @@ static void __interrupt __far prvYieldProcessor( void )
|
||||||
static void prvPortResetPIC( void )
|
static void prvPortResetPIC( void )
|
||||||
{
|
{
|
||||||
/* We are going to call the DOS tick interrupt at as close a
|
/* We are going to call the DOS tick interrupt at as close a
|
||||||
frequency to the normal DOS tick as possible. */
|
* frequency to the normal DOS tick as possible. */
|
||||||
|
|
||||||
/* WE SHOULD NOT DO THIS IF YIELD WAS CALLED. */
|
/* WE SHOULD NOT DO THIS IF YIELD WAS CALLED. */
|
||||||
--sDOSTickCounter;
|
--sDOSTickCounter;
|
||||||
|
|
||||||
if( sDOSTickCounter <= 0 )
|
if( sDOSTickCounter <= 0 )
|
||||||
{
|
{
|
||||||
sDOSTickCounter = ( int16_t ) portTICKS_PER_DOS_TICK;
|
sDOSTickCounter = ( int16_t ) portTICKS_PER_DOS_TICK;
|
||||||
__asm{ int portSWITCH_INT_NUMBER + 1 };
|
__asm {
|
||||||
|
int portSWITCH_INT_NUMBER + 1
|
||||||
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Reset the PIC as the DOS tick is not being called to
|
/* Reset the PIC as the DOS tick is not being called to
|
||||||
do it. */
|
* do it. */
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
mov al, 20H
|
mov al, 20H
|
||||||
|
@ -225,19 +230,20 @@ static void prvPortResetPIC( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Jump back to the processor state prior to starting the
|
/* Jump back to the processor state prior to starting the
|
||||||
scheduler. This means we are not going to be using a
|
* scheduler. This means we are not going to be using a
|
||||||
task stack frame so the task can be deleted. */
|
* task stack frame so the task can be deleted. */
|
||||||
longjmp( xJumpBuf, 1 );
|
longjmp( xJumpBuf, 1 );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvExitFunction( void )
|
static void prvExitFunction( void )
|
||||||
{
|
{
|
||||||
void ( __interrupt __far *pxOriginalTickISR )();
|
void( __interrupt __far * pxOriginalTickISR )();
|
||||||
|
|
||||||
/* Interrupts should be disabled here anyway - but no
|
/* Interrupts should be disabled here anyway - but no
|
||||||
harm in making sure. */
|
* harm in making sure. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if( xSchedulerRunning == pdTRUE )
|
if( xSchedulerRunning == pdTRUE )
|
||||||
{
|
{
|
||||||
/* Set the DOS tick back onto the timer ticker. */
|
/* Set the DOS tick back onto the timer ticker. */
|
||||||
|
@ -246,28 +252,29 @@ void ( __interrupt __far *pxOriginalTickISR )();
|
||||||
prvSetTickFrequencyDefault();
|
prvSetTickFrequencyDefault();
|
||||||
|
|
||||||
/* Put back the switch interrupt routines that was in place
|
/* Put back the switch interrupt routines that was in place
|
||||||
before the scheduler started. */
|
* before the scheduler started. */
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOldSwitchISRPlus1 );
|
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOldSwitchISRPlus1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The tick timer is back how DOS wants it. We can re-enable
|
/* The tick timer is back how DOS wants it. We can re-enable
|
||||||
interrupts without the scheduler being called. */
|
* interrupts without the scheduler being called. */
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
||||||
{
|
{
|
||||||
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
||||||
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
||||||
const uint32_t ulPIT_CONST = ( uint32_t ) 1193180UL;
|
const uint32_t ulPIT_CONST = ( uint32_t ) 1193180UL;
|
||||||
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
||||||
uint32_t ulOutput;
|
uint32_t ulOutput;
|
||||||
|
|
||||||
/* Setup the 8245 to tick at the wanted frequency. */
|
/* Setup the 8245 to tick at the wanted frequency. */
|
||||||
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
||||||
ulOutput = ulPIT_CONST / ulTickRateHz;
|
ulOutput = ulPIT_CONST / ulTickRateHz;
|
||||||
portOUTPUT_BYTE( usPIT0, ( uint16_t )( ulOutput & ( uint32_t ) 0xff ) );
|
portOUTPUT_BYTE( usPIT0, ( uint16_t ) ( ulOutput & ( uint32_t ) 0xff ) );
|
||||||
ulOutput >>= 8;
|
ulOutput >>= 8;
|
||||||
portOUTPUT_BYTE( usPIT0, ( uint16_t ) ( ulOutput & ( uint32_t ) 0xff ) );
|
portOUTPUT_BYTE( usPIT0, ( uint16_t ) ( ulOutput & ( uint32_t ) 0xff ) );
|
||||||
}
|
}
|
||||||
|
@ -275,13 +282,13 @@ uint32_t ulOutput;
|
||||||
|
|
||||||
static void prvSetTickFrequencyDefault( void )
|
static void prvSetTickFrequencyDefault( void )
|
||||||
{
|
{
|
||||||
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
||||||
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
||||||
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
||||||
|
|
||||||
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
||||||
portOUTPUT_BYTE( usPIT0,0 );
|
portOUTPUT_BYTE( usPIT0, 0 );
|
||||||
portOUTPUT_BYTE( usPIT0,0 );
|
portOUTPUT_BYTE( usPIT0, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,60 +40,61 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT long
|
#define portFLOAT long
|
||||||
#define portDOUBLE long
|
#define portDOUBLE long
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT int
|
#define portSHORT int
|
||||||
#define portSTACK_TYPE uint16_t
|
#define portSTACK_TYPE uint16_t
|
||||||
#define portBASE_TYPE portSHORT
|
#define portBASE_TYPE portSHORT
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef short BaseType_t;
|
typedef short BaseType_t;
|
||||||
typedef unsigned short UBaseType_t;
|
typedef unsigned short UBaseType_t;
|
||||||
|
|
||||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#else
|
#else
|
||||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
#define portENTER_CRITICAL() __asm{ pushf } \
|
#define portENTER_CRITICAL() \
|
||||||
__asm{ cli } \
|
__asm { pushf } \
|
||||||
|
__asm { cli } \
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() __asm{ popf }
|
#define portEXIT_CRITICAL() __asm { popf }
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() __asm{ cli }
|
#define portDISABLE_INTERRUPTS() __asm { cli }
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() __asm{ sti }
|
#define portENABLE_INTERRUPTS() __asm { sti }
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portNOP() __asm{ nop }
|
#define portNOP() __asm { nop }
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portSWITCH_INT_NUMBER 0x80
|
#define portSWITCH_INT_NUMBER 0x80
|
||||||
#define portYIELD() __asm{ int portSWITCH_INT_NUMBER }
|
#define portYIELD() __asm { int portSWITCH_INT_NUMBER }
|
||||||
#define portDOS_TICK_RATE ( 18.20648 )
|
#define portDOS_TICK_RATE ( 18.20648 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portTICKS_PER_DOS_TICK ( ( uint16_t ) ( ( ( portDOUBLE ) configTICK_RATE_HZ / portDOS_TICK_RATE ) + 0.5 ) )
|
#define portTICKS_PER_DOS_TICK ( ( uint16_t ) ( ( ( portDOUBLE ) configTICK_RATE_HZ / portDOS_TICK_RATE ) + 0.5 ) )
|
||||||
#define portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */
|
#define portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */
|
||||||
#define portBYTE_ALIGNMENT ( 2 )
|
#define portBYTE_ALIGNMENT ( 2 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Compiler specifics. */
|
/* Compiler specifics. */
|
||||||
#define portINPUT_BYTE( xAddr ) inp( xAddr )
|
#define portINPUT_BYTE( xAddr ) inp( xAddr )
|
||||||
#define portOUTPUT_BYTE( xAddr, ucValue ) outp( xAddr, ucValue )
|
#define portOUTPUT_BYTE( xAddr, ucValue ) outp( xAddr, ucValue )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vTaskFunction, pvParameters ) void vTaskFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vTaskFunction, pvParameters ) void vTaskFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vTaskFunction, pvParameters ) void vTaskFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vTaskFunction, pvParameters ) void vTaskFunction( void * pvParameters )
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
@ -48,40 +48,40 @@ void portSWITCH_CONTEXT( void );
|
||||||
void portFIRST_CONTEXT( void );
|
void portFIRST_CONTEXT( void );
|
||||||
|
|
||||||
/* There are slightly different versions depending on whether you are building
|
/* There are slightly different versions depending on whether you are building
|
||||||
to include debugger information. If debugger information is used then there
|
* to include debugger information. If debugger information is used then there
|
||||||
are a couple of extra bytes left of the ISR stack (presumably for use by the
|
* are a couple of extra bytes left of the ISR stack (presumably for use by the
|
||||||
debugger). The true stack pointer is then stored in the bp register. We add
|
* debugger). The true stack pointer is then stored in the bp register. We add
|
||||||
2 to the stack pointer to remove the extra bytes before we restore our context. */
|
* 2 to the stack pointer to remove the extra bytes before we restore our context. */
|
||||||
|
|
||||||
#define portSWITCH_CONTEXT() \
|
#define portSWITCH_CONTEXT() \
|
||||||
asm { mov ax, seg pxCurrentTCB } \
|
asm { mov ax, seg pxCurrentTCB } \
|
||||||
asm { mov ds, ax } \
|
asm { mov ds, ax } \
|
||||||
asm { les bx, pxCurrentTCB } /* Save the stack pointer into the TCB. */ \
|
asm { les bx, pxCurrentTCB } /* Save the stack pointer into the TCB. */ \
|
||||||
asm { mov es:0x2[ bx ], ss } \
|
asm { mov es : 0x2[ bx ], ss } \
|
||||||
asm { mov es:[ bx ], sp } \
|
asm { mov es:[ bx ], sp } \
|
||||||
asm { call far ptr vTaskSwitchContext } /* Perform the switch. */ \
|
asm { call far ptr vTaskSwitchContext } /* Perform the switch. */ \
|
||||||
asm { mov ax, seg pxCurrentTCB } /* Restore the stack pointer from the TCB. */ \
|
asm { mov ax, seg pxCurrentTCB } /* Restore the stack pointer from the TCB. */ \
|
||||||
asm { mov ds, ax } \
|
asm { mov ds, ax } \
|
||||||
asm { les bx, dword ptr pxCurrentTCB } \
|
asm { les bx, dword ptr pxCurrentTCB } \
|
||||||
asm { mov ss, es:[ bx + 2 ] } \
|
asm { mov ss, es:[ bx + 2 ] } \
|
||||||
asm { mov sp, es:[ bx ] }
|
asm { mov sp, es:[ bx ] }
|
||||||
|
|
||||||
#define portFIRST_CONTEXT() \
|
#define portFIRST_CONTEXT() \
|
||||||
__asm { mov ax, seg pxCurrentTCB } \
|
__asm { mov ax, seg pxCurrentTCB } \
|
||||||
__asm { mov ds, ax } \
|
__asm { mov ds, ax } \
|
||||||
__asm { les bx, dword ptr pxCurrentTCB } \
|
__asm { les bx, dword ptr pxCurrentTCB } \
|
||||||
__asm { mov ss, es:[ bx + 2 ] } \
|
__asm { mov ss, es:[ bx + 2 ] } \
|
||||||
__asm { mov sp, es:[ bx ] } \
|
__asm { mov sp, es:[ bx ] } \
|
||||||
__asm { pop bp } \
|
__asm { pop bp } \
|
||||||
__asm { pop di } \
|
__asm { pop di } \
|
||||||
__asm { pop si } \
|
__asm { pop si } \
|
||||||
__asm { pop ds } \
|
__asm { pop ds } \
|
||||||
__asm { pop es } \
|
__asm { pop es } \
|
||||||
__asm { pop dx } \
|
__asm { pop dx } \
|
||||||
__asm { pop cx } \
|
__asm { pop cx } \
|
||||||
__asm { pop bx } \
|
__asm { pop bx } \
|
||||||
__asm { pop ax } \
|
__asm { pop ax } \
|
||||||
__asm { iret }
|
__asm { iret }
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif /* ifndef PORT_ASM_H */
|
||||||
|
|
|
@ -27,16 +27,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V1.00:
|
* Changes from V1.00:
|
||||||
|
*
|
||||||
+ pxPortInitialiseStack() now initialises the stack of new tasks to the
|
+ pxPortInitialiseStack() now initialises the stack of new tasks to the
|
||||||
same format used by the compiler. This allows the compiler generated
|
+ same format used by the compiler. This allows the compiler generated
|
||||||
interrupt mechanism to be used for context switches.
|
+ interrupt mechanism to be used for context switches.
|
||||||
|
+
|
||||||
Changes from V2.6.1
|
+ Changes from V2.6.1
|
||||||
|
+
|
||||||
+ Move usPortCheckFreeStackSpace() to tasks.c.
|
+ Move usPortCheckFreeStackSpace() to tasks.c.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
|
@ -46,12 +46,14 @@ Changes from V2.6.1
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* See header file for description. */
|
/* See header file for description. */
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
StackType_t DS_Reg = 0;
|
StackType_t DS_Reg = 0;
|
||||||
|
|
||||||
/* Place a few bytes of known values on the bottom of the stack.
|
/* Place a few bytes of known values on the bottom of the stack.
|
||||||
This is just useful for debugging. */
|
* This is just useful for debugging. */
|
||||||
|
|
||||||
*pxTopOfStack = 0x1111;
|
*pxTopOfStack = 0x1111;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -68,8 +70,8 @@ StackType_t DS_Reg = 0;
|
||||||
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
||||||
|
|
||||||
/* We are going to start the scheduler using a return from interrupt
|
/* We are going to start the scheduler using a return from interrupt
|
||||||
instruction to load the program counter, so first there would be the
|
* instruction to load the program counter, so first there would be the
|
||||||
function call with parameters preamble. */
|
* function call with parameters preamble. */
|
||||||
|
|
||||||
*pxTopOfStack = FP_SEG( pvParameters );
|
*pxTopOfStack = FP_SEG( pvParameters );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -89,8 +91,8 @@ StackType_t DS_Reg = 0;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The remaining registers would be pushed on the stack by our context
|
/* The remaining registers would be pushed on the stack by our context
|
||||||
switch function. These are loaded with values simply to make debugging
|
* switch function. These are loaded with values simply to make debugging
|
||||||
easier. */
|
* easier. */
|
||||||
*pxTopOfStack = ( StackType_t ) 0xAAAA; /* AX */
|
*pxTopOfStack = ( StackType_t ) 0xAAAA; /* AX */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0xBBBB; /* BX */
|
*pxTopOfStack = ( StackType_t ) 0xBBBB; /* BX */
|
||||||
|
@ -103,9 +105,11 @@ StackType_t DS_Reg = 0;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* We need the true data segment. */
|
/* We need the true data segment. */
|
||||||
__asm{ MOV DS_Reg, DS };
|
__asm {
|
||||||
|
MOV DS_Reg, DS
|
||||||
|
};
|
||||||
|
|
||||||
*pxTopOfStack = DS_Reg; /* DS */
|
*pxTopOfStack = DS_Reg; /* DS */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x0123; /* SI */
|
*pxTopOfStack = ( StackType_t ) 0x0123; /* SI */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
32
portable/CCS/ARM_CM3/port.c
Executable file → Normal file
32
portable/CCS/ARM_CM3/port.c
Executable file → Normal file
|
@ -265,22 +265,22 @@ BaseType_t xPortStartScheduler( void )
|
||||||
if( ulImplementedPrioBits == 8 )
|
if( ulImplementedPrioBits == 8 )
|
||||||
{
|
{
|
||||||
/* When the hardware implements 8 priority bits, there is no way for
|
/* When the hardware implements 8 priority bits, there is no way for
|
||||||
* the software to configure PRIGROUP to not have sub-priorities. As
|
* the software to configure PRIGROUP to not have sub-priorities. As
|
||||||
* a result, the least significant bit is always used for sub-priority
|
* a result, the least significant bit is always used for sub-priority
|
||||||
* and there are 128 preemption priorities and 2 sub-priorities.
|
* and there are 128 preemption priorities and 2 sub-priorities.
|
||||||
*
|
*
|
||||||
* This may cause some confusion in some cases - for example, if
|
* This may cause some confusion in some cases - for example, if
|
||||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
|
||||||
* priority interrupts will be masked in Critical Sections as those
|
* priority interrupts will be masked in Critical Sections as those
|
||||||
* are at the same preemption priority. This may appear confusing as
|
* are at the same preemption priority. This may appear confusing as
|
||||||
* 4 is higher (numerically lower) priority than
|
* 4 is higher (numerically lower) priority than
|
||||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
|
||||||
* have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
|
* have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||||
* to 4, this confusion does not happen and the behaviour remains the same.
|
* to 4, this confusion does not happen and the behaviour remains the same.
|
||||||
*
|
*
|
||||||
* The following assert ensures that the sub-priority bit in the
|
* The following assert ensures that the sub-priority bit in the
|
||||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
|
||||||
* confusion. */
|
* confusion. */
|
||||||
configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
|
configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
|
||||||
ulMaxPRIGROUPValue = 0;
|
ulMaxPRIGROUPValue = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -47,124 +47,124 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 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. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#else
|
#else
|
||||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Compiler directives. */
|
/* Compiler directives. */
|
||||||
#define portWEAK_SYMBOL __attribute__( ( weak ) )
|
#define portWEAK_SYMBOL __attribute__( ( weak ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
#define portYIELD() \
|
#define portYIELD() \
|
||||||
{ \
|
{ \
|
||||||
/* Set a PendSV to request a context switch. */ \
|
/* Set a PendSV to request a context switch. */ \
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
__asm( " dsb"); \
|
__asm( " dsb" ); \
|
||||||
__asm( " isb"); \
|
__asm( " isb" ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 )
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD( ); } while( 0 )
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if ( configMAX_PRIORITIES > 32 )
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( ( uxReadyPriorities ) ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
{ \
|
{ \
|
||||||
_set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \
|
_set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \
|
||||||
__asm( " dsb"); \
|
__asm( " dsb" ); \
|
||||||
__asm( " isb"); \
|
__asm( " isb" ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() _set_interrupt_priority( 0 )
|
#define portENABLE_INTERRUPTS() _set_interrupt_priority( 0 )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() _set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); __asm( " dsb" ); __asm( " isb")
|
#define portSET_INTERRUPT_MASK_FROM_ISR() _set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); __asm( " dsb" ); __asm( " isb" )
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) _set_interrupt_priority( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) _set_interrupt_priority( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Tickless idle/low power functionality. */
|
/* Tickless idle/low power functionality. */
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
* not necessary for to use this port. They are defined so the common demo files
|
* not necessary for to use this port. They are defined so the common demo files
|
||||||
* (which build with all the ports) will build. */
|
* (which build with all the ports) will build. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
void vPortValidateInterruptPriority( void );
|
void vPortValidateInterruptPriority( void );
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* portNOP() is not required by this port. */
|
/* portNOP() is not required by this port. */
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
32
portable/CCS/ARM_CM4F/port.c
Executable file → Normal file
32
portable/CCS/ARM_CM4F/port.c
Executable file → Normal file
|
@ -284,22 +284,22 @@ BaseType_t xPortStartScheduler( void )
|
||||||
if( ulImplementedPrioBits == 8 )
|
if( ulImplementedPrioBits == 8 )
|
||||||
{
|
{
|
||||||
/* When the hardware implements 8 priority bits, there is no way for
|
/* When the hardware implements 8 priority bits, there is no way for
|
||||||
* the software to configure PRIGROUP to not have sub-priorities. As
|
* the software to configure PRIGROUP to not have sub-priorities. As
|
||||||
* a result, the least significant bit is always used for sub-priority
|
* a result, the least significant bit is always used for sub-priority
|
||||||
* and there are 128 preemption priorities and 2 sub-priorities.
|
* and there are 128 preemption priorities and 2 sub-priorities.
|
||||||
*
|
*
|
||||||
* This may cause some confusion in some cases - for example, if
|
* This may cause some confusion in some cases - for example, if
|
||||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
|
||||||
* priority interrupts will be masked in Critical Sections as those
|
* priority interrupts will be masked in Critical Sections as those
|
||||||
* are at the same preemption priority. This may appear confusing as
|
* are at the same preemption priority. This may appear confusing as
|
||||||
* 4 is higher (numerically lower) priority than
|
* 4 is higher (numerically lower) priority than
|
||||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
|
||||||
* have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
|
* have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||||
* to 4, this confusion does not happen and the behaviour remains the same.
|
* to 4, this confusion does not happen and the behaviour remains the same.
|
||||||
*
|
*
|
||||||
* The following assert ensures that the sub-priority bit in the
|
* The following assert ensures that the sub-priority bit in the
|
||||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
|
||||||
* confusion. */
|
* confusion. */
|
||||||
configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
|
configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
|
||||||
ulMaxPRIGROUPValue = 0;
|
ulMaxPRIGROUPValue = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -47,118 +47,118 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 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. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#else
|
#else
|
||||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
#define portYIELD() \
|
#define portYIELD() \
|
||||||
{ \
|
{ \
|
||||||
/* Set a PendSV to request a context switch. */ \
|
/* Set a PendSV to request a context switch. */ \
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
__asm( " dsb"); \
|
__asm( " dsb" ); \
|
||||||
__asm( " isb"); \
|
__asm( " isb" ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 )
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD( ); } while( 0 )
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if ( configMAX_PRIORITIES > 32 )
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( ( uxReadyPriorities ) ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
{ \
|
{ \
|
||||||
_set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \
|
_set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \
|
||||||
__asm( " dsb"); \
|
__asm( " dsb" ); \
|
||||||
__asm( " isb"); \
|
__asm( " isb" ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() _set_interrupt_priority( 0 )
|
#define portENABLE_INTERRUPTS() _set_interrupt_priority( 0 )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() _set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); __asm( " dsb" ); __asm( " isb")
|
#define portSET_INTERRUPT_MASK_FROM_ISR() _set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); __asm( " dsb" ); __asm( " isb" )
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) _set_interrupt_priority( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) _set_interrupt_priority( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Tickless idle/low power functionality. */
|
/* Tickless idle/low power functionality. */
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
* not necessary for to use this port. They are defined so the common demo files
|
* not necessary for to use this port. They are defined so the common demo files
|
||||||
* (which build with all the ports) will build. */
|
* (which build with all the ports) will build. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
void vPortValidateInterruptPriority( void );
|
void vPortValidateInterruptPriority( void );
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* portNOP() is not required by this port. */
|
/* portNOP() is not required by this port. */
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -38,27 +38,27 @@ uint32_t ulCriticalNesting = 9999;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Registers required to configure the RTI. */
|
/* Registers required to configure the RTI. */
|
||||||
#define portRTI_GCTRL_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC00 ) )
|
#define portRTI_GCTRL_REG ( *( ( volatile uint32_t * ) 0xFFFFFC00 ) )
|
||||||
#define portRTI_TBCTRL_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC04 ) )
|
#define portRTI_TBCTRL_REG ( *( ( volatile uint32_t * ) 0xFFFFFC04 ) )
|
||||||
#define portRTI_COMPCTRL_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC0C ) )
|
#define portRTI_COMPCTRL_REG ( *( ( volatile uint32_t * ) 0xFFFFFC0C ) )
|
||||||
#define portRTI_CNT0_FRC0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC10 ) )
|
#define portRTI_CNT0_FRC0_REG ( *( ( volatile uint32_t * ) 0xFFFFFC10 ) )
|
||||||
#define portRTI_CNT0_UC0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC14 ) )
|
#define portRTI_CNT0_UC0_REG ( *( ( volatile uint32_t * ) 0xFFFFFC14 ) )
|
||||||
#define portRTI_CNT0_CPUC0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC18 ) )
|
#define portRTI_CNT0_CPUC0_REG ( *( ( volatile uint32_t * ) 0xFFFFFC18 ) )
|
||||||
#define portRTI_CNT0_COMP0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC50 ) )
|
#define portRTI_CNT0_COMP0_REG ( *( ( volatile uint32_t * ) 0xFFFFFC50 ) )
|
||||||
#define portRTI_CNT0_UDCP0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC54 ) )
|
#define portRTI_CNT0_UDCP0_REG ( *( ( volatile uint32_t * ) 0xFFFFFC54 ) )
|
||||||
#define portRTI_SETINTENA_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC80 ) )
|
#define portRTI_SETINTENA_REG ( *( ( volatile uint32_t * ) 0xFFFFFC80 ) )
|
||||||
#define portRTI_CLEARINTENA_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC84 ) )
|
#define portRTI_CLEARINTENA_REG ( *( ( volatile uint32_t * ) 0xFFFFFC84 ) )
|
||||||
#define portRTI_INTFLAG_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC88 ) )
|
#define portRTI_INTFLAG_REG ( *( ( volatile uint32_t * ) 0xFFFFFC88 ) )
|
||||||
|
|
||||||
|
|
||||||
/* Constants required to set up the initial stack of each task. */
|
/* Constants required to set up the initial stack of each task. */
|
||||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1F )
|
#define portINITIAL_SPSR ( ( StackType_t ) 0x1F )
|
||||||
#define portINITIAL_FPSCR ( ( StackType_t ) 0x00 )
|
#define portINITIAL_FPSCR ( ( StackType_t ) 0x00 )
|
||||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 0x04 )
|
#define portINSTRUCTION_SIZE ( ( StackType_t ) 0x04 )
|
||||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||||
|
|
||||||
/* The number of words on the stack frame between the saved Top Of Stack and
|
/* The number of words on the stack frame between the saved Top Of Stack and
|
||||||
R0 (in which the parameters are passed. */
|
* R0 (in which the parameters are passed. */
|
||||||
#define portSPACE_BETWEEN_TOS_AND_PARAMETERS ( 12 )
|
#define portSPACE_BETWEEN_TOS_AND_PARAMETERS ( 12 )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -69,7 +69,7 @@ extern void vPortStartFirstTask( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Saved as part of the task context. Set to pdFALSE if the task does not
|
/* Saved as part of the task context. Set to pdFALSE if the task does not
|
||||||
require an FPU context. */
|
* require an FPU context. */
|
||||||
uint32_t ulTaskHasFPUContext = 0;
|
uint32_t ulTaskHasFPUContext = 0;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -78,9 +78,11 @@ uint32_t ulTaskHasFPUContext = 0;
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
StackType_t *pxOriginalTOS;
|
StackType_t * pxOriginalTOS;
|
||||||
|
|
||||||
pxOriginalTOS = pxTopOfStack;
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
|
@ -92,15 +94,15 @@ StackType_t *pxOriginalTOS;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro. */
|
* expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First on the stack is the return address - which is the start of the as
|
/* First on the stack is the return address - which is the start of the as
|
||||||
the task has not executed yet. The offset is added to make the return
|
* the task has not executed yet. The offset is added to make the return
|
||||||
address appear as it would within an IRQ ISR. */
|
* address appear as it would within an IRQ ISR. */
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */
|
*pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -132,11 +134,11 @@ StackType_t *pxOriginalTOS;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
}
|
}
|
||||||
#else
|
#else /* ifdef portPRELOAD_TASK_REGISTERS */
|
||||||
{
|
{
|
||||||
pxTopOfStack -= portSPACE_BETWEEN_TOS_AND_PARAMETERS;
|
pxTopOfStack -= portSPACE_BETWEEN_TOS_AND_PARAMETERS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* ifdef portPRELOAD_TASK_REGISTERS */
|
||||||
|
|
||||||
/* Function parameters are passed in R0. */
|
/* Function parameters are passed in R0. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
|
@ -156,8 +158,8 @@ StackType_t *pxOriginalTOS;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The last thing on the stack is the tasks ulUsingFPU value, which by
|
/* The last thing on the stack is the tasks ulUsingFPU value, which by
|
||||||
default is set to indicate that the stack frame does not include FPU
|
* default is set to indicate that the stack frame does not include FPU
|
||||||
registers. */
|
* registers. */
|
||||||
*pxTopOfStack = pdFALSE;
|
*pxTopOfStack = pdFALSE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -166,7 +168,7 @@ StackType_t *pxOriginalTOS;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvSetupTimerInterrupt(void)
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
/* Disable timer 0. */
|
/* Disable timer 0. */
|
||||||
portRTI_GCTRL_REG &= 0xFFFFFFFEUL;
|
portRTI_GCTRL_REG &= 0xFFFFFFFEUL;
|
||||||
|
@ -178,8 +180,8 @@ static void prvSetupTimerInterrupt(void)
|
||||||
portRTI_COMPCTRL_REG = 0x00000000U;
|
portRTI_COMPCTRL_REG = 0x00000000U;
|
||||||
|
|
||||||
/* Initialise the counter and the prescale counter registers. */
|
/* Initialise the counter and the prescale counter registers. */
|
||||||
portRTI_CNT0_UC0_REG = 0x00000000U;
|
portRTI_CNT0_UC0_REG = 0x00000000U;
|
||||||
portRTI_CNT0_FRC0_REG = 0x00000000U;
|
portRTI_CNT0_FRC0_REG = 0x00000000U;
|
||||||
|
|
||||||
/* Set Prescalar for RTI clock. */
|
/* Set Prescalar for RTI clock. */
|
||||||
portRTI_CNT0_CPUC0_REG = 0x00000001U;
|
portRTI_CNT0_CPUC0_REG = 0x00000001U;
|
||||||
|
@ -187,7 +189,7 @@ static void prvSetupTimerInterrupt(void)
|
||||||
portRTI_CNT0_UDCP0_REG = ( configCPU_CLOCK_HZ / 2 ) / configTICK_RATE_HZ;
|
portRTI_CNT0_UDCP0_REG = ( configCPU_CLOCK_HZ / 2 ) / configTICK_RATE_HZ;
|
||||||
|
|
||||||
/* Clear interrupts. */
|
/* Clear interrupts. */
|
||||||
portRTI_INTFLAG_REG = 0x0007000FU;
|
portRTI_INTFLAG_REG = 0x0007000FU;
|
||||||
portRTI_CLEARINTENA_REG = 0x00070F0FU;
|
portRTI_CLEARINTENA_REG = 0x00070F0FU;
|
||||||
|
|
||||||
/* Enable the compare 0 interrupt. */
|
/* Enable the compare 0 interrupt. */
|
||||||
|
@ -199,7 +201,7 @@ static void prvSetupTimerInterrupt(void)
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
BaseType_t xPortStartScheduler(void)
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. */
|
/* Start the timer that generates the tick ISR. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
@ -208,7 +210,7 @@ BaseType_t xPortStartScheduler(void)
|
||||||
ulCriticalNesting = 0;
|
ulCriticalNesting = 0;
|
||||||
|
|
||||||
/* Start the first task. This is done from portASM.asm as ARM mode must be
|
/* Start the first task. This is done from portASM.asm as ARM mode must be
|
||||||
used. */
|
* used. */
|
||||||
vPortStartFirstTask();
|
vPortStartFirstTask();
|
||||||
|
|
||||||
/* Should not get here! */
|
/* Should not get here! */
|
||||||
|
@ -219,40 +221,40 @@ BaseType_t xPortStartScheduler(void)
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
void vPortEndScheduler(void)
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Not implemented in ports where there is nothing to return to.
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
Artificially force an assert. */
|
* Artificially force an assert. */
|
||||||
configASSERT( ulCriticalNesting == 1000UL );
|
configASSERT( ulCriticalNesting == 1000UL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
* simply increment the system tick. */
|
* simply increment the system tick. */
|
||||||
__interrupt void vPortNonPreemptiveTick( void )
|
__interrupt void vPortNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* clear clock interrupt flag */
|
/* clear clock interrupt flag */
|
||||||
portRTI_INTFLAG_REG = 0x00000001;
|
portRTI_INTFLAG_REG = 0x00000001;
|
||||||
|
|
||||||
/* Increment the tick count - this may make a delaying task ready
|
/* Increment the tick count - this may make a delaying task ready
|
||||||
to run - but a context switch is not performed. */
|
* to run - but a context switch is not performed. */
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else /* if configUSE_PREEMPTION == 0 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
* The preemptive scheduler ISR is written in assembler and can be found
|
* The preemptive scheduler ISR is written in assembler and can be found
|
||||||
* in the portASM.asm file. This will only get used if portUSE_PREEMPTION
|
* in the portASM.asm file. This will only get used if portUSE_PREEMPTION
|
||||||
* is set to 1 in portmacro.h
|
* is set to 1 in portmacro.h
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
*/
|
*/
|
||||||
void vPortPreemptiveTick( void );
|
void vPortPreemptiveTick( void );
|
||||||
|
|
||||||
#endif
|
#endif /* if configUSE_PREEMPTION == 0 */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -264,9 +266,9 @@ void vPortEnterCritical( void )
|
||||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now that interrupts are disabled, ulCriticalNesting can be accessed
|
||||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
portENTER_CRITICAL() has been called. */
|
* portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -283,7 +285,7 @@ void vPortExitCritical( void )
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then interrupts should be
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
re-enabled. */
|
* re-enabled. */
|
||||||
if( ulCriticalNesting == 0 )
|
if( ulCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
/* Enable interrupts as per portENABLE_INTERRUPTS(). */
|
/* Enable interrupts as per portENABLE_INTERRUPTS(). */
|
||||||
|
@ -297,10 +299,10 @@ void vPortExitCritical( void )
|
||||||
|
|
||||||
void vPortTaskUsesFPU( void )
|
void vPortTaskUsesFPU( void )
|
||||||
{
|
{
|
||||||
extern void vPortInitialiseFPSCR( void );
|
extern void vPortInitialiseFPSCR( void );
|
||||||
|
|
||||||
/* A task is registering the fact that it needs an FPU context. Set the
|
/* A task is registering the fact that it needs an FPU context. Set the
|
||||||
FPU flag (saved as part of the task context. */
|
* FPU flag (saved as part of the task context. */
|
||||||
ulTaskHasFPUContext = pdTRUE;
|
ulTaskHasFPUContext = pdTRUE;
|
||||||
|
|
||||||
/* Initialise the floating point status register. */
|
/* Initialise the floating point status register. */
|
||||||
|
|
|
@ -40,80 +40,80 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if (configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS)
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY (TickType_t) 0xFFFF
|
#define portMAX_DELAY ( TickType_t ) 0xFFFF
|
||||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY (TickType_t) 0xFFFFFFFFF
|
#define portMAX_DELAY ( TickType_t ) 0xFFFFFFFFF
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 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. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#else
|
#else
|
||||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#define portSTACK_GROWTH (-1)
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ((TickType_t) 1000 / configTICK_RATE_HZ)
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
|
||||||
/* Critical section handling. */
|
/* Critical section handling. */
|
||||||
extern void vPortEnterCritical(void);
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical(void);
|
extern void vPortExitCritical( void );
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
#define portDISABLE_INTERRUPTS() asm( " CPSID I" )
|
#define portDISABLE_INTERRUPTS() asm ( " CPSID I" )
|
||||||
#define portENABLE_INTERRUPTS() asm( " CPSIE I" )
|
#define portENABLE_INTERRUPTS() asm ( " CPSIE I" )
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
#pragma SWI_ALIAS( vPortYield, 0 )
|
#pragma SWI_ALIAS( vPortYield, 0 )
|
||||||
extern void vPortYield( void );
|
extern void vPortYield( void );
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portSYS_SSIR1_REG ( * ( ( volatile uint32_t * ) 0xFFFFFFB0 ) )
|
#define portSYS_SSIR1_REG ( *( ( volatile uint32_t * ) 0xFFFFFFB0 ) )
|
||||||
#define portSYS_SSIR1_SSKEY ( 0x7500UL )
|
#define portSYS_SSIR1_SSKEY ( 0x7500UL )
|
||||||
#define portYIELD_WITHIN_API() { portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; asm( " DSB " ); asm( " ISB " ); }
|
#define portYIELD_WITHIN_API() { portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; asm ( " DSB " ); asm ( " ISB " ); }
|
||||||
#define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) { portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; ( void ) portSYS_SSIR1_REG; } } while( 0 )
|
#define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) { portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; ( void ) portSYS_SSIR1_REG; } } while( 0 )
|
||||||
|
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if( configMAX_PRIORITIES > 32 )
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( ( uxReadyPriorities ) ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void *pvParameters)
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION_PROTO(vFunction, pvParameters) void vFunction(void *pvParameters)
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
#endif /* __PORTMACRO_H__ */
|
#endif /* __PORTMACRO_H__ */
|
||||||
|
|
|
@ -1,49 +1,53 @@
|
||||||
;/*
|
; /*
|
||||||
; * FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
* ; * FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
; *
|
* ; *
|
||||||
; * SPDX-License-Identifier: MIT
|
* ; * SPDX-License-Identifier: MIT
|
||||||
; *
|
* ; *
|
||||||
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* ; * 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
|
* ; * this software and associated documentation files (the "Software"), to deal in
|
||||||
; * the Software without restriction, including without limitation the rights to
|
* ; * the Software without restriction, including without limitation the rights to
|
||||||
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
* ; * 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,
|
* ; * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
; * subject to the following conditions:
|
* ; * subject to the following conditions:
|
||||||
; *
|
* ; *
|
||||||
; * The above copyright notice and this permission notice shall be included in all
|
* ; * The above copyright notice and this permission notice shall be included in all
|
||||||
; * copies or substantial portions of the Software.
|
* ; * copies or substantial portions of the Software.
|
||||||
; *
|
* ; *
|
||||||
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
* ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
* ; * 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
|
* ; * 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
|
* ; * 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.
|
* ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
; *
|
* ; *
|
||||||
; * https://www.FreeRTOS.org
|
* ; * https://www.FreeRTOS.org
|
||||||
; * https://github.com/FreeRTOS
|
* ; * https://github.com/FreeRTOS
|
||||||
; *
|
* ; *
|
||||||
; */
|
* ; */
|
||||||
|
|
||||||
.if $DEFINED( __LARGE_DATA_MODEL__ )
|
.
|
||||||
.define "pushm.a", pushm_x
|
|
||||||
.define "popm.a", popm_x
|
|
||||||
.define "push.a", push_x
|
|
||||||
.define "pop.a", pop_x
|
|
||||||
.define "mov.a", mov_x
|
|
||||||
.else
|
|
||||||
.define "pushm.w", pushm_x
|
|
||||||
.define "popm.w", popm_x
|
|
||||||
.define "push.w", push_x
|
|
||||||
.define "pop.w", pop_x
|
|
||||||
.define "mov.w", mov_x
|
|
||||||
.endif
|
|
||||||
|
|
||||||
.if $DEFINED( __LARGE_CODE_MODEL__ )
|
if $DEFINED( __LARGE_DATA_MODEL__ )
|
||||||
.define "calla", call_x
|
.define "pushm.a", pushm_x
|
||||||
.define "reta", ret_x
|
.define "popm.a", popm_x
|
||||||
.else
|
.define "push.a", push_x
|
||||||
|
.define "pop.a", pop_x
|
||||||
|
.define "mov.a", mov_x
|
||||||
|
.else
|
||||||
|
.define "pushm.w", pushm_x
|
||||||
|
.define "popm.w", popm_x
|
||||||
|
.define "push.w", push_x
|
||||||
|
.define "pop.w", pop_x
|
||||||
|
.define "mov.w", mov_x
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
if $DEFINED( __LARGE_CODE_MODEL__ )
|
||||||
|
.define "calla", call_x
|
||||||
|
.define "reta", ret_x
|
||||||
|
.else
|
||||||
.define "call", call_x
|
.define "call", call_x
|
||||||
.define "ret", ret_x
|
.define "ret", ret_x
|
||||||
.endif
|
.endif
|
||||||
|
|
|
@ -31,28 +31,28 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the MSP430X port.
|
* Implementation of functions defined in portable.h for the MSP430X port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Constants required for hardware setup. The tick ISR runs off the ACLK,
|
/* Constants required for hardware setup. The tick ISR runs off the ACLK,
|
||||||
not the MCLK. */
|
* not the MCLK. */
|
||||||
#define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 )
|
#define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 )
|
||||||
#define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 )
|
#define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 )
|
||||||
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 )
|
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 )
|
||||||
|
|
||||||
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
||||||
any details of its type. */
|
* any details of its type. */
|
||||||
typedef void TCB_t;
|
typedef void TCB_t;
|
||||||
extern volatile TCB_t * volatile pxCurrentTCB;
|
extern volatile TCB_t * volatile pxCurrentTCB;
|
||||||
|
|
||||||
/* Each task maintains a count of the critical section nesting depth. Each
|
/* Each task maintains a count of the critical section nesting depth. Each
|
||||||
time a critical section is entered the count is incremented. Each time a
|
* time a critical section is entered the count is incremented. Each time a
|
||||||
critical section is exited the count is decremented - with interrupts only
|
* critical section is exited the count is decremented - with interrupts only
|
||||||
being re-enabled if the count is zero.
|
* being re-enabled if the count is zero.
|
||||||
|
*
|
||||||
usCriticalNesting will get set to zero when the scheduler starts, but must
|
* usCriticalNesting will get set to zero when the scheduler starts, but must
|
||||||
not be initialised to zero as this will cause problems during the startup
|
* not be initialised to zero as this will cause problems during the startup
|
||||||
sequence. */
|
* sequence. */
|
||||||
volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -70,25 +70,27 @@ void vPortSetupTimerInterrupt( void );
|
||||||
*
|
*
|
||||||
* See the header file portable.h.
|
* See the header file portable.h.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
uint16_t *pusTopOfStack;
|
uint16_t * pusTopOfStack;
|
||||||
uint32_t *pulTopOfStack, ulTemp;
|
uint32_t * pulTopOfStack, ulTemp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Place a few bytes of known values on the bottom of the stack.
|
* Place a few bytes of known values on the bottom of the stack.
|
||||||
This is just useful for debugging and can be included if required.
|
* This is just useful for debugging and can be included if required.
|
||||||
|
*
|
||||||
*pxTopOfStack = ( StackType_t ) 0x1111;
|
* pxTopOfStack = ( StackType_t ) 0x1111;
|
||||||
pxTopOfStack--;
|
* pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x2222;
|
* pxTopOfStack = ( StackType_t ) 0x2222;
|
||||||
pxTopOfStack--;
|
* pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x3333;
|
* pxTopOfStack = ( StackType_t ) 0x3333;
|
||||||
pxTopOfStack--;
|
* pxTopOfStack--;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Data types are need either 16 bits or 32 bits depending on the data
|
/* Data types are need either 16 bits or 32 bits depending on the data
|
||||||
and code model used. */
|
* and code model used. */
|
||||||
if( sizeof( pxCode ) == sizeof( uint16_t ) )
|
if( sizeof( pxCode ) == sizeof( uint16_t ) )
|
||||||
{
|
{
|
||||||
pusTopOfStack = ( uint16_t * ) pxTopOfStack;
|
pusTopOfStack = ( uint16_t * ) pxTopOfStack;
|
||||||
|
@ -137,19 +139,19 @@ uint32_t *pulTopOfStack, ulTemp;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x4444;
|
*pxTopOfStack = ( StackType_t ) 0x4444;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
#else
|
#else /* ifdef PRELOAD_REGISTER_VALUES */
|
||||||
pxTopOfStack -= 3;
|
pxTopOfStack -= 3;
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||||
pxTopOfStack -= 9;
|
pxTopOfStack -= 9;
|
||||||
#endif
|
#endif /* ifdef PRELOAD_REGISTER_VALUES */
|
||||||
|
|
||||||
/* A variable is used to keep track of the critical section nesting.
|
/* A variable is used to keep track of the critical section nesting.
|
||||||
This variable has to be stored as part of the task context and is
|
* This variable has to be stored as part of the task context and is
|
||||||
initially set to zero. */
|
* initially set to zero. */
|
||||||
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
/* Return a pointer to the top of the stack we have generated so this can
|
/* Return a pointer to the top of the stack we have generated so this can
|
||||||
be stored in the task control block for the task. */
|
* be stored in the task control block for the task. */
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -157,7 +159,7 @@ uint32_t *pulTopOfStack, ulTemp;
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the MSP430 port will get stopped. If required simply
|
/* It is unlikely that the MSP430 port will get stopped. If required simply
|
||||||
disable the tick interrupt here. */
|
* disable the tick interrupt here. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -173,7 +175,7 @@ void vPortSetupTimerInterrupt( void )
|
||||||
#pragma vector=configTICK_VECTOR
|
#pragma vector=configTICK_VECTOR
|
||||||
interrupt void vTickISREntry( void )
|
interrupt void vTickISREntry( void )
|
||||||
{
|
{
|
||||||
extern void vPortTickISR( void );
|
extern void vPortTickISR( void );
|
||||||
|
|
||||||
__bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
|
__bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
|
||||||
#if configUSE_PREEMPTION == 1
|
#if configUSE_PREEMPTION == 1
|
||||||
|
@ -184,5 +186,3 @@ extern void vPortTickISR( void );
|
||||||
vPortCooperativeTickISR();
|
vPortCooperativeTickISR();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,31 +43,31 @@
|
||||||
#include "msp430.h"
|
#include "msp430.h"
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT int
|
#define portSHORT int
|
||||||
#define portBASE_TYPE portSHORT
|
#define portBASE_TYPE portSHORT
|
||||||
|
|
||||||
/* The stack type changes depending on the data model. */
|
/* The stack type changes depending on the data model. */
|
||||||
#ifdef __LARGE_DATA_MODEL__
|
#ifdef __LARGE_DATA_MODEL__
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#else
|
#else
|
||||||
#define portSTACK_TYPE uint16_t
|
#define portSTACK_TYPE uint16_t
|
||||||
#define portPOINTER_SIZE_TYPE uint16_t
|
#define portPOINTER_SIZE_TYPE uint16_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef short BaseType_t;
|
typedef short BaseType_t;
|
||||||
typedef unsigned short UBaseType_t;
|
typedef unsigned short UBaseType_t;
|
||||||
|
|
||||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
||||||
#else
|
#else
|
||||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
#endif
|
#endif
|
||||||
|
@ -80,37 +80,37 @@ typedef unsigned short UBaseType_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section control macros. */
|
/* Critical section control macros. */
|
||||||
#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 )
|
#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 )
|
||||||
|
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint16_t usCriticalNesting; \
|
extern volatile uint16_t usCriticalNesting; \
|
||||||
\
|
\
|
||||||
portDISABLE_INTERRUPTS(); \
|
portDISABLE_INTERRUPTS(); \
|
||||||
\
|
\
|
||||||
/* Now interrupts are disabled usCriticalNesting can be accessed */ \
|
/* Now interrupts are disabled usCriticalNesting can be accessed */ \
|
||||||
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
|
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
|
||||||
/* times portENTER_CRITICAL() has been called. */ \
|
/* times portENTER_CRITICAL() has been called. */ \
|
||||||
usCriticalNesting++; \
|
usCriticalNesting++; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() \
|
#define portEXIT_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint16_t usCriticalNesting; \
|
extern volatile uint16_t usCriticalNesting; \
|
||||||
\
|
\
|
||||||
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
|
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
|
||||||
{ \
|
{ \
|
||||||
/* Decrement the nesting count as we are leaving a critical section. */ \
|
/* Decrement the nesting count as we are leaving a critical section. */ \
|
||||||
usCriticalNesting--; \
|
usCriticalNesting--; \
|
||||||
\
|
\
|
||||||
/* If the nesting level has reached zero then interrupts should be */ \
|
/* If the nesting level has reached zero then interrupts should be */ \
|
||||||
/* re-enabled. */ \
|
/* re-enabled. */ \
|
||||||
if( usCriticalNesting == portNO_CRITICAL_SECTION_NESTING ) \
|
if( usCriticalNesting == portNO_CRITICAL_SECTION_NESTING ) \
|
||||||
{ \
|
{ \
|
||||||
portENABLE_INTERRUPTS(); \
|
portENABLE_INTERRUPTS(); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
@ -119,27 +119,27 @@ extern volatile uint16_t usCriticalNesting;
|
||||||
* Manual context switch called by portYIELD or taskYIELD.
|
* Manual context switch called by portYIELD or taskYIELD.
|
||||||
*/
|
*/
|
||||||
extern void vPortYield( void );
|
extern void vPortYield( void );
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 2
|
#define portBYTE_ALIGNMENT 2
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portNOP() __no_operation()
|
#define portNOP() __no_operation()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
extern void vTaskSwitchContext( void );
|
extern void vTaskSwitchContext( void );
|
||||||
#define portYIELD_FROM_ISR( x ) do { if( x ) vPortYield(); } while( 0 )
|
#define portYIELD_FROM_ISR( x ) do { if( x ) vPortYield( ); } while( 0 )
|
||||||
|
|
||||||
void vApplicationSetupTimerInterrupt( void );
|
void vApplicationSetupTimerInterrupt( void );
|
||||||
|
|
||||||
/* sizeof( int ) != sizeof( long ) so a full printf() library is required if
|
/* sizeof( int ) != sizeof( long ) so a full printf() library is required if
|
||||||
run time stats information is to be displayed. */
|
* run time stats information is to be displayed. */
|
||||||
#define portLU_PRINTF_SPECIFIER_REQUIRED
|
#define portLU_PRINTF_SPECIFIER_REQUIRED
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
@ -31,35 +31,38 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
|
|
||||||
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
||||||
|
|
||||||
/* Supervisor mode set. */
|
/* Supervisor mode set. */
|
||||||
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000)
|
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000 )
|
||||||
|
|
||||||
/* The clock prescale into the timer peripheral. */
|
/* The clock prescale into the timer peripheral. */
|
||||||
#define portPRESCALE_VALUE ( ( uint8_t ) 10 )
|
#define portPRESCALE_VALUE ( ( uint8_t ) 10 )
|
||||||
|
|
||||||
/* The clock frequency into the RTC. */
|
/* The clock frequency into the RTC. */
|
||||||
#define portRTC_CLOCK_HZ ( ( uint32_t ) 1000 )
|
#define portRTC_CLOCK_HZ ( ( uint32_t ) 1000 )
|
||||||
|
|
||||||
asm void interrupt VectorNumber_VL1swi vPortYieldISR( void );
|
asm void interrupt VectorNumber_VL1swi vPortYieldISR( void );
|
||||||
static void prvSetupTimerInterrupt( void );
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
||||||
will be set to 0 prior to the first task being started. */
|
* will be set to 0 prior to the first task being started. */
|
||||||
static uint32_t ulCriticalNesting = 0x9999UL;
|
static uint32_t ulCriticalNesting = 0x9999UL;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
|
uint32_t ulOriginalA5;
|
||||||
|
|
||||||
uint32_t ulOriginalA5;
|
__asm {
|
||||||
|
MOVE.L A5, ulOriginalA5
|
||||||
__asm{ MOVE.L A5, ulOriginalA5 };
|
};
|
||||||
|
|
||||||
|
|
||||||
*pxTopOfStack = (StackType_t) 0xDEADBEEF;
|
*pxTopOfStack = ( StackType_t ) 0xDEADBEEF;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Exception stack frame starts with the return address. */
|
/* Exception stack frame starts with the return address. */
|
||||||
|
@ -70,12 +73,12 @@ uint32_t ulOriginalA5;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
*pxTopOfStack = ( StackType_t ) 0x0; /*FP*/
|
*pxTopOfStack = ( StackType_t ) 0x0; /*FP*/
|
||||||
pxTopOfStack -= 14; /* A5 to D0. */
|
pxTopOfStack -= 14; /* A5 to D0. */
|
||||||
|
|
||||||
/* Parameter in A0. */
|
/* Parameter in A0. */
|
||||||
*( pxTopOfStack + 8 ) = ( StackType_t ) pvParameters;
|
*( pxTopOfStack + 8 ) = ( StackType_t ) pvParameters;
|
||||||
|
|
||||||
/* A5 must be maintained as it is resurved by the compiler. */
|
/* A5 must be maintained as it is reserved by the compiler. */
|
||||||
*( pxTopOfStack + 13 ) = ulOriginalA5;
|
*( pxTopOfStack + 13 ) = ulOriginalA5;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -84,7 +87,7 @@ uint32_t ulOriginalA5;
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
extern void vPortStartFirstTask( void );
|
extern void vPortStartFirstTask( void );
|
||||||
|
|
||||||
ulCriticalNesting = 0UL;
|
ulCriticalNesting = 0UL;
|
||||||
|
|
||||||
|
@ -107,7 +110,7 @@ static void prvSetupTimerInterrupt( void )
|
||||||
RTCMOD = portRTC_CLOCK_HZ / configTICK_RATE_HZ;
|
RTCMOD = portRTC_CLOCK_HZ / configTICK_RATE_HZ;
|
||||||
|
|
||||||
/* Enable the RTC to generate interrupts - interrupts are already disabled
|
/* Enable the RTC to generate interrupts - interrupts are already disabled
|
||||||
when this code executes. */
|
* when this code executes. */
|
||||||
RTCSC_RTIE = 1;
|
RTCSC_RTIE = 1;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -123,19 +126,20 @@ void vPortEnterCritical( void )
|
||||||
if( ulCriticalNesting == 0UL )
|
if( ulCriticalNesting == 0UL )
|
||||||
{
|
{
|
||||||
/* Guard against context switches being pended simultaneously with a
|
/* Guard against context switches being pended simultaneously with a
|
||||||
critical section being entered. */
|
* critical section being entered. */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if( INTC_FRC == 0UL )
|
if( INTC_FRC == 0UL )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
} while( 1 );
|
} while( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -143,6 +147,7 @@ void vPortEnterCritical( void )
|
||||||
void vPortExitCritical( void )
|
void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
if( ulCriticalNesting == 0 )
|
if( ulCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
@ -152,7 +157,7 @@ void vPortExitCritical( void )
|
||||||
|
|
||||||
void vPortYieldHandler( void )
|
void vPortYieldHandler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulSavedInterruptMask;
|
uint32_t ulSavedInterruptMask;
|
||||||
|
|
||||||
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
{
|
{
|
||||||
|
@ -166,7 +171,7 @@ uint32_t ulSavedInterruptMask;
|
||||||
|
|
||||||
void interrupt VectorNumber_Vrtc vPortTickISR( void )
|
void interrupt VectorNumber_Vrtc vPortTickISR( void )
|
||||||
{
|
{
|
||||||
uint32_t ulSavedInterruptMask;
|
uint32_t ulSavedInterruptMask;
|
||||||
|
|
||||||
/* Clear the interrupt. */
|
/* Clear the interrupt. */
|
||||||
RTCSC |= RTCSC_RTIF_MASK;
|
RTCSC |= RTCSC_RTIF_MASK;
|
||||||
|
|
|
@ -46,34 +46,34 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
|
|
||||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
||||||
#else
|
#else
|
||||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 4
|
#define portBYTE_ALIGNMENT 4
|
||||||
#define portSTACK_GROWTH -1
|
#define portSTACK_GROWTH -1
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
uint32_t ulPortSetIPL( uint32_t );
|
uint32_t ulPortSetIPL( uint32_t );
|
||||||
|
@ -83,30 +83,30 @@ uint32_t ulPortSetIPL( uint32_t );
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
extern UBaseType_t uxPortSetInterruptMaskFromISR( void );
|
extern UBaseType_t uxPortSetInterruptMaskFromISR( void );
|
||||||
extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
#define portNOP() asm volatile ( "nop" )
|
#define portNOP() asm volatile ( "nop" )
|
||||||
|
|
||||||
/* Context switches are requested using the force register. */
|
/* Context switches are requested using the force register. */
|
||||||
#define portYIELD() INTC_SFRC = 0x3E; portNOP(); portNOP(); portNOP(); portNOP(); portNOP()
|
#define portYIELD() INTC_SFRC = 0x3E; portNOP(); portNOP(); portNOP(); portNOP(); portNOP()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__((noreturn))
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) __attribute__( ( noreturn ) )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) { portYIELD(); } } while( 0 )
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) { portYIELD(); } } while( 0 )
|
||||||
|
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
|
|
|
@ -31,39 +31,41 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
|
|
||||||
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
||||||
|
|
||||||
/* Supervisor mode set. */
|
/* Supervisor mode set. */
|
||||||
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000)
|
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000 )
|
||||||
|
|
||||||
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
||||||
will be set to 0 prior to the first task being started. */
|
* will be set to 0 prior to the first task being started. */
|
||||||
static uint32_t ulCriticalNesting = 0x9999UL;
|
static uint32_t ulCriticalNesting = 0x9999UL;
|
||||||
|
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
lea.l (-60, %sp), %sp; \
|
lea.l( -60, % sp ), % sp; \
|
||||||
movem.l %d0-%fp, (%sp); \
|
movem.l % d0 - % fp, ( % sp ); \
|
||||||
move.l pxCurrentTCB, %a0; \
|
move.l pxCurrentTCB, % a0; \
|
||||||
move.l %sp, (%a0);
|
move.l % sp, ( % a0 );
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
move.l pxCurrentTCB, %a0; \
|
move.l pxCurrentTCB, % a0; \
|
||||||
move.l (%a0), %sp; \
|
move.l( % a0 ), % sp; \
|
||||||
movem.l (%sp), %d0-%fp; \
|
movem.l( % sp ), % d0 - % fp; \
|
||||||
lea.l %sp@(60), %sp; \
|
lea.l % sp@( 60 ), % sp; \
|
||||||
rte
|
rte
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
*pxTopOfStack = (StackType_t) 0xDEADBEEF;
|
*pxTopOfStack = ( StackType_t ) 0xDEADBEEF;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Exception stack frame starts with the return address. */
|
/* Exception stack frame starts with the return address. */
|
||||||
|
@ -74,7 +76,7 @@ StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t p
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
*pxTopOfStack = ( StackType_t ) 0x0; /*FP*/
|
*pxTopOfStack = ( StackType_t ) 0x0; /*FP*/
|
||||||
pxTopOfStack -= 14; /* A5 to D0. */
|
pxTopOfStack -= 14; /* A5 to D0. */
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +84,7 @@ StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t p
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
extern void vPortStartFirstTask( void );
|
extern void vPortStartFirstTask( void );
|
||||||
|
|
||||||
ulCriticalNesting = 0UL;
|
ulCriticalNesting = 0UL;
|
||||||
|
|
||||||
|
@ -107,19 +109,20 @@ void vPortEnterCritical( void )
|
||||||
if( ulCriticalNesting == 0UL )
|
if( ulCriticalNesting == 0UL )
|
||||||
{
|
{
|
||||||
/* Guard against context switches being pended simultaneously with a
|
/* Guard against context switches being pended simultaneously with a
|
||||||
critical section being entered. */
|
* critical section being entered. */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if( MCF_INTC0_INTFRCH == 0UL )
|
if( MCF_INTC0_INTFRCH == 0UL )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
} while( 1 );
|
} while( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -127,6 +130,7 @@ void vPortEnterCritical( void )
|
||||||
void vPortExitCritical( void )
|
void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
if( ulCriticalNesting == 0 )
|
if( ulCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
@ -136,12 +140,12 @@ void vPortExitCritical( void )
|
||||||
|
|
||||||
void vPortYieldHandler( void )
|
void vPortYieldHandler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulSavedInterruptMask;
|
uint32_t ulSavedInterruptMask;
|
||||||
|
|
||||||
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
/* Note this will clear all forced interrupts - this is done for speed. */
|
/* Note this will clear all forced interrupts - this is done for speed. */
|
||||||
MCF_INTC0_INTFRCL = 0;
|
MCF_INTC0_INTFRCL = 0;
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
@ -46,33 +46,33 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
||||||
#else
|
#else
|
||||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 4
|
#define portBYTE_ALIGNMENT 4
|
||||||
#define portSTACK_GROWTH -1
|
#define portSTACK_GROWTH -1
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
uint32_t ulPortSetIPL( uint32_t );
|
uint32_t ulPortSetIPL( uint32_t );
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
@ -81,31 +81,31 @@ uint32_t ulPortSetIPL( uint32_t );
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
extern UBaseType_t uxPortSetInterruptMaskFromISR( void );
|
extern UBaseType_t uxPortSetInterruptMaskFromISR( void );
|
||||||
extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
||||||
#define portNOP() asm volatile ( "nop" )
|
#define portNOP() asm volatile ( "nop" )
|
||||||
|
|
||||||
/* Note this will overwrite all other bits in the force register, it is done this way for speed. */
|
/* Note this will overwrite all other bits in the force register, it is done this way for speed. */
|
||||||
#define portYIELD() MCF_INTC0_INTFRCL = ( 1UL << configYIELD_INTERRUPT_VECTOR ); portNOP(); portNOP() /* -32 as we are using the high word of the 64bit mask. */
|
#define portYIELD() MCF_INTC0_INTFRCL = ( 1UL << configYIELD_INTERRUPT_VECTOR ); portNOP(); portNOP() /* -32 as we are using the high word of the 64bit mask. */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__((noreturn))
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) __attribute__( ( noreturn ) )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) { portYIELD(); } } while( 0 )
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) { portYIELD(); } } while( 0 )
|
||||||
|
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the HCS12 port.
|
* Implementation of functions defined in portable.h for the HCS12 port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -43,29 +43,29 @@
|
||||||
static void prvSetupTimerInterrupt( void );
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
/* Interrupt service routines have to be in non-banked memory - as does the
|
/* Interrupt service routines have to be in non-banked memory - as does the
|
||||||
scheduler startup function. */
|
* scheduler startup function. */
|
||||||
#pragma CODE_SEG __NEAR_SEG NON_BANKED
|
#pragma CODE_SEG __NEAR_SEG NON_BANKED
|
||||||
|
|
||||||
/* Manual context switch function. This is the SWI ISR. */
|
/* Manual context switch function. This is the SWI ISR. */
|
||||||
void interrupt vPortYield( void );
|
void interrupt vPortYield( void );
|
||||||
|
|
||||||
/* Tick context switch function. This is the timer ISR. */
|
/* Tick context switch function. This is the timer ISR. */
|
||||||
void interrupt vPortTickInterrupt( void );
|
void interrupt vPortTickInterrupt( void );
|
||||||
|
|
||||||
/* Simply called by xPortStartScheduler(). xPortStartScheduler() does not
|
/* Simply called by xPortStartScheduler(). xPortStartScheduler() does not
|
||||||
start the scheduler directly because the header file containing the
|
* start the scheduler directly because the header file containing the
|
||||||
xPortStartScheduler() prototype is part of the common kernel code, and
|
* xPortStartScheduler() prototype is part of the common kernel code, and
|
||||||
therefore cannot use the CODE_SEG pragma. */
|
* therefore cannot use the CODE_SEG pragma. */
|
||||||
static BaseType_t xBankedStartScheduler( void );
|
static BaseType_t xBankedStartScheduler( void );
|
||||||
|
|
||||||
#pragma CODE_SEG DEFAULT
|
#pragma CODE_SEG DEFAULT
|
||||||
|
|
||||||
/* Calls to portENTER_CRITICAL() can be nested. When they are nested the
|
/* Calls to portENTER_CRITICAL() can be nested. When they are nested the
|
||||||
critical section should not be left (i.e. interrupts should not be re-enabled)
|
* critical section should not be left (i.e. interrupts should not be re-enabled)
|
||||||
until the nesting depth reaches 0. This variable simply tracks the nesting
|
* until the nesting depth reaches 0. This variable simply tracks the nesting
|
||||||
depth. Each task maintains it's own critical nesting depth variable so
|
* depth. Each task maintains it's own critical nesting depth variable so
|
||||||
uxCriticalNesting is saved and restored from the task stack during a context
|
* uxCriticalNesting is saved and restored from the task stack during a context
|
||||||
switch. */
|
* switch. */
|
||||||
volatile UBaseType_t uxCriticalNesting = 0xff;
|
volatile UBaseType_t uxCriticalNesting = 0xff;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -73,31 +73,33 @@ volatile UBaseType_t uxCriticalNesting = 0xff;
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Place a few bytes of known values on the bottom of the stack.
|
* Place a few bytes of known values on the bottom of the stack.
|
||||||
This can be uncommented to provide useful stack markers when debugging.
|
* This can be uncommented to provide useful stack markers when debugging.
|
||||||
|
*
|
||||||
*pxTopOfStack = ( StackType_t ) 0x11;
|
* pxTopOfStack = ( StackType_t ) 0x11;
|
||||||
pxTopOfStack--;
|
* pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x22;
|
* pxTopOfStack = ( StackType_t ) 0x22;
|
||||||
pxTopOfStack--;
|
* pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x33;
|
* pxTopOfStack = ( StackType_t ) 0x33;
|
||||||
pxTopOfStack--;
|
* pxTopOfStack--;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro. In this case the stack as
|
* expected by the portRESTORE_CONTEXT() macro. In this case the stack as
|
||||||
expected by the HCS12 RTI instruction. */
|
* expected by the HCS12 RTI instruction. */
|
||||||
|
|
||||||
|
|
||||||
/* The address of the task function is placed in the stack byte at a time. */
|
/* The address of the task function is placed in the stack byte at a time. */
|
||||||
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pxCode) ) + 1 );
|
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pxCode ) ) + 1 );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pxCode) ) + 0 );
|
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pxCode ) ) + 0 );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Next are all the registers that form part of the task context. */
|
/* Next are all the registers that form part of the task context. */
|
||||||
|
@ -115,15 +117,15 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* A register contains parameter high byte. */
|
/* A register contains parameter high byte. */
|
||||||
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pvParameters) ) + 0 );
|
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pvParameters ) ) + 0 );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* B register contains parameter low byte. */
|
/* B register contains parameter low byte. */
|
||||||
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pvParameters) ) + 1 );
|
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pvParameters ) ) + 1 );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* CCR: Note that when the task starts interrupts will be enabled since
|
/* CCR: Note that when the task starts interrupts will be enabled since
|
||||||
"I" bit of CCR is cleared */
|
* "I" bit of CCR is cleared */
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00;
|
*pxTopOfStack = ( StackType_t ) 0x00;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
@ -134,7 +136,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Finally the critical nesting depth is initialised with 0 (not within
|
/* Finally the critical nesting depth is initialised with 0 (not within
|
||||||
a critical section). */
|
* a critical section). */
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00;
|
*pxTopOfStack = ( StackType_t ) 0x00;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -157,10 +159,10 @@ static void prvSetupTimerInterrupt( void )
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* xPortStartScheduler() does not start the scheduler directly because
|
/* xPortStartScheduler() does not start the scheduler directly because
|
||||||
the header file containing the xPortStartScheduler() prototype is part
|
* the header file containing the xPortStartScheduler() prototype is part
|
||||||
of the common kernel code, and therefore cannot use the CODE_SEG pragma.
|
* of the common kernel code, and therefore cannot use the CODE_SEG pragma.
|
||||||
Instead it simply calls the locally defined xBankedStartScheduler() -
|
* Instead it simply calls the locally defined xBankedStartScheduler() -
|
||||||
which does use the CODE_SEG pragma. */
|
* which does use the CODE_SEG pragma. */
|
||||||
|
|
||||||
return xBankedStartScheduler();
|
return xBankedStartScheduler();
|
||||||
}
|
}
|
||||||
|
@ -171,7 +173,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
static BaseType_t xBankedStartScheduler( void )
|
static BaseType_t xBankedStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Configure the timer that will generate the RTOS tick. Interrupts are
|
/* Configure the timer that will generate the RTOS tick. Interrupts are
|
||||||
disabled when this function is called. */
|
* disabled when this function is called. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Restore the context of the first task. */
|
/* Restore the context of the first task. */
|
||||||
|
@ -222,15 +224,15 @@ void interrupt vPortTickInterrupt( void )
|
||||||
TFLG1 = 1;
|
TFLG1 = 1;
|
||||||
|
|
||||||
/* Restore the context of a task - which may be a different task
|
/* Restore the context of a task - which may be a different task
|
||||||
to that interrupted. */
|
* to that interrupted. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
#else
|
#else /* if configUSE_PREEMPTION == 1 */
|
||||||
{
|
{
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
TFLG1 = 1;
|
TFLG1 = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* if configUSE_PREEMPTION == 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma CODE_SEG DEFAULT
|
#pragma CODE_SEG DEFAULT
|
||||||
|
|
|
@ -41,40 +41,40 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint8_t
|
#define portSTACK_TYPE uint8_t
|
||||||
#define portBASE_TYPE char
|
#define portBASE_TYPE char
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef signed char BaseType_t;
|
typedef signed char BaseType_t;
|
||||||
typedef unsigned char UBaseType_t;
|
typedef unsigned char UBaseType_t;
|
||||||
|
|
||||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
||||||
#else
|
#else
|
||||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 1
|
#define portBYTE_ALIGNMENT 1
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portYIELD() __asm( "swi" );
|
#define portYIELD() __asm( "swi" );
|
||||||
#define portNOP() __asm( "nop" );
|
#define portNOP() __asm( "nop" );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section handling. */
|
/* Critical section handling. */
|
||||||
#define portENABLE_INTERRUPTS() __asm( "cli" )
|
#define portENABLE_INTERRUPTS() __asm( "cli" )
|
||||||
#define portDISABLE_INTERRUPTS() __asm( "sei" )
|
#define portDISABLE_INTERRUPTS() __asm( "sei" )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disable interrupts before incrementing the count of critical section nesting.
|
* Disable interrupts before incrementing the count of critical section nesting.
|
||||||
|
@ -82,29 +82,29 @@ typedef unsigned char UBaseType_t;
|
||||||
* re-enabled. Once interrupts are disabled the nesting count can be accessed
|
* re-enabled. Once interrupts are disabled the nesting count can be accessed
|
||||||
* directly. Each task maintains its own nesting count.
|
* directly. Each task maintains its own nesting count.
|
||||||
*/
|
*/
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile UBaseType_t uxCriticalNesting; \
|
extern volatile UBaseType_t uxCriticalNesting; \
|
||||||
\
|
\
|
||||||
portDISABLE_INTERRUPTS(); \
|
portDISABLE_INTERRUPTS(); \
|
||||||
uxCriticalNesting++; \
|
uxCriticalNesting++; \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interrupts are disabled so we can access the nesting count directly. If the
|
* Interrupts are disabled so we can access the nesting count directly. If the
|
||||||
* nesting is found to be 0 (no nesting) then we are leaving the critical
|
* nesting is found to be 0 (no nesting) then we are leaving the critical
|
||||||
* section and interrupts can be re-enabled.
|
* section and interrupts can be re-enabled.
|
||||||
*/
|
*/
|
||||||
#define portEXIT_CRITICAL() \
|
#define portEXIT_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile UBaseType_t uxCriticalNesting; \
|
extern volatile UBaseType_t uxCriticalNesting; \
|
||||||
\
|
\
|
||||||
uxCriticalNesting--; \
|
uxCriticalNesting--; \
|
||||||
if( uxCriticalNesting == 0 ) \
|
if( uxCriticalNesting == 0 ) \
|
||||||
{ \
|
{ \
|
||||||
portENABLE_INTERRUPTS(); \
|
portENABLE_INTERRUPTS(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
@ -120,70 +120,71 @@ typedef unsigned char UBaseType_t;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef BANKED_MODEL
|
#ifdef BANKED_MODEL
|
||||||
/*
|
|
||||||
* Load the stack pointer for the task, then pull the critical nesting
|
/*
|
||||||
* count and PPAGE register from the stack. The remains of the
|
* Load the stack pointer for the task, then pull the critical nesting
|
||||||
* context are restored by the RTI instruction.
|
* count and PPAGE register from the stack. The remains of the
|
||||||
*/
|
* context are restored by the RTI instruction.
|
||||||
#define portRESTORE_CONTEXT() \
|
*/
|
||||||
{ \
|
#define portRESTORE_CONTEXT() \
|
||||||
extern volatile void * pxCurrentTCB; \
|
{ \
|
||||||
extern volatile UBaseType_t uxCriticalNesting; \
|
extern volatile void * pxCurrentTCB; \
|
||||||
\
|
extern volatile UBaseType_t uxCriticalNesting; \
|
||||||
__asm( "ldx pxCurrentTCB" ); \
|
\
|
||||||
__asm( "lds 0, x" ); \
|
__asm( "ldx pxCurrentTCB" ); \
|
||||||
__asm( "pula" ); \
|
__asm( "lds 0, x" ); \
|
||||||
__asm( "staa uxCriticalNesting" ); \
|
__asm( "pula" ); \
|
||||||
__asm( "pula" ); \
|
__asm( "staa uxCriticalNesting" ); \
|
||||||
__asm( "staa 0x30" ); /* 0x30 = PPAGE */ \
|
__asm( "pula" ); \
|
||||||
|
__asm( "staa 0x30" ); /* 0x30 = PPAGE */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* By the time this macro is called the processor has already stacked the
|
* By the time this macro is called the processor has already stacked the
|
||||||
* registers. Simply stack the nesting count and PPAGE value, then save
|
* registers. Simply stack the nesting count and PPAGE value, then save
|
||||||
* the task stack pointer.
|
* the task stack pointer.
|
||||||
*/
|
*/
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * pxCurrentTCB; \
|
extern volatile void * pxCurrentTCB; \
|
||||||
extern volatile UBaseType_t uxCriticalNesting; \
|
extern volatile UBaseType_t uxCriticalNesting; \
|
||||||
\
|
\
|
||||||
__asm( "ldaa 0x30" ); /* 0x30 = PPAGE */ \
|
__asm( "ldaa 0x30" ); /* 0x30 = PPAGE */ \
|
||||||
__asm( "psha" ); \
|
__asm( "psha" ); \
|
||||||
__asm( "ldaa uxCriticalNesting" ); \
|
__asm( "ldaa uxCriticalNesting" ); \
|
||||||
__asm( "psha" ); \
|
__asm( "psha" ); \
|
||||||
__asm( "ldx pxCurrentTCB" ); \
|
__asm( "ldx pxCurrentTCB" ); \
|
||||||
__asm( "sts 0, x" ); \
|
__asm( "sts 0, x" ); \
|
||||||
}
|
}
|
||||||
#else
|
#else /* ifdef BANKED_MODEL */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These macros are as per the BANKED versions above, but without saving
|
* These macros are as per the BANKED versions above, but without saving
|
||||||
* and restoring the PPAGE register.
|
* and restoring the PPAGE register.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * pxCurrentTCB; \
|
extern volatile void * pxCurrentTCB; \
|
||||||
extern volatile UBaseType_t uxCriticalNesting; \
|
extern volatile UBaseType_t uxCriticalNesting; \
|
||||||
\
|
\
|
||||||
__asm( "ldx pxCurrentTCB" ); \
|
__asm( "ldx pxCurrentTCB" ); \
|
||||||
__asm( "lds 0, x" ); \
|
__asm( "lds 0, x" ); \
|
||||||
__asm( "pula" ); \
|
__asm( "pula" ); \
|
||||||
__asm( "staa uxCriticalNesting" ); \
|
__asm( "staa uxCriticalNesting" ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * pxCurrentTCB; \
|
extern volatile void * pxCurrentTCB; \
|
||||||
extern volatile UBaseType_t uxCriticalNesting; \
|
extern volatile UBaseType_t uxCriticalNesting; \
|
||||||
\
|
\
|
||||||
__asm( "ldaa uxCriticalNesting" ); \
|
__asm( "ldaa uxCriticalNesting" ); \
|
||||||
__asm( "psha" ); \
|
__asm( "psha" ); \
|
||||||
__asm( "ldx pxCurrentTCB" ); \
|
__asm( "ldx pxCurrentTCB" ); \
|
||||||
__asm( "sts 0, x" ); \
|
__asm( "sts 0, x" ); \
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* ifdef BANKED_MODEL */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility macro to call macros above in correct order in order to perform a
|
* Utility macro to call macros above in correct order in order to perform a
|
||||||
|
@ -191,14 +192,14 @@ typedef unsigned char UBaseType_t;
|
||||||
* the ISR does not use any local (stack) variables. If the ISR uses stack
|
* the ISR does not use any local (stack) variables. If the ISR uses stack
|
||||||
* variables portYIELD() should be used in it's place.
|
* variables portYIELD() should be used in it's place.
|
||||||
*/
|
*/
|
||||||
#define portTASK_SWITCH_FROM_ISR() \
|
#define portTASK_SWITCH_FROM_ISR() \
|
||||||
portSAVE_CONTEXT(); \
|
portSAVE_CONTEXT(); \
|
||||||
vTaskSwitchContext(); \
|
vTaskSwitchContext(); \
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
@ -28,13 +28,13 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the Atmel AT91R40008
|
* Implementation of functions defined in portable.h for the Atmel AT91R40008
|
||||||
* port.
|
* port.
|
||||||
*
|
*
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in this file. The ISR routines, which can only be compiled
|
* contained in this file. The ISR routines, which can only be compiled
|
||||||
* to ARM mode are contained in portISR.c.
|
* to ARM mode are contained in portISR.c.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -50,11 +50,11 @@
|
||||||
#include "tc.h"
|
#include "tc.h"
|
||||||
|
|
||||||
/* Constants required to setup the task context. */
|
/* Constants required to setup the task context. */
|
||||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
||||||
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
||||||
#define portTICK_PRIORITY_6 ( 6 )
|
#define portTICK_PRIORITY_6 ( 6 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Setup the timer to generate the tick interrupts. */
|
/* Setup the timer to generate the tick interrupts. */
|
||||||
|
@ -74,61 +74,63 @@ extern void vPortISRStartFirstTask( void );
|
||||||
*
|
*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
StackType_t *pxOriginalTOS;
|
StackType_t * pxOriginalTOS;
|
||||||
|
|
||||||
pxOriginalTOS = pxTopOfStack;
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
is not really required. */
|
* is not really required. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro. */
|
* expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First on the stack is the return address - which in this case is the
|
/* First on the stack is the return address - which in this case is the
|
||||||
start of the task. The offset is added to make the return address appear
|
* start of the task. The offset is added to make the return address appear
|
||||||
as it would within an IRQ ISR. */
|
* as it would within an IRQ ISR. */
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
*pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */
|
*pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* When the task starts is will expect to find the function parameter in
|
/* When the task starts is will expect to find the function parameter in
|
||||||
R0. */
|
* R0. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The last thing onto the stack is the status register, which is set for
|
/* The last thing onto the stack is the status register, which is set for
|
||||||
system mode, with interrupts enabled. */
|
* system mode, with interrupts enabled. */
|
||||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
@ -141,9 +143,9 @@ StackType_t *pxOriginalTOS;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Some optimisation levels use the stack differently to others. This
|
/* Some optimisation levels use the stack differently to others. This
|
||||||
means the interrupt flags cannot always be stored on the stack and will
|
* means the interrupt flags cannot always be stored on the stack and will
|
||||||
instead be stored in a variable, which is then saved as part of the
|
* instead be stored in a variable, which is then saved as part of the
|
||||||
tasks context. */
|
* tasks context. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -153,7 +155,7 @@ StackType_t *pxOriginalTOS;
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
here already. */
|
* here already. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
|
@ -167,7 +169,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the ARM port will require this function as there
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
is nothing to return to. */
|
* is nothing to return to. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -176,7 +178,7 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulDummy;
|
volatile uint32_t ulDummy;
|
||||||
|
|
||||||
/* Enable clock to the tick timer... */
|
/* Enable clock to the tick timer... */
|
||||||
AT91C_BASE_PS->PS_PCER = portTIMER_CLK_ENABLE_BIT;
|
AT91C_BASE_PS->PS_PCER = portTIMER_CLK_ENABLE_BIT;
|
||||||
|
@ -191,17 +193,17 @@ volatile uint32_t ulDummy;
|
||||||
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
||||||
|
|
||||||
/* Store interrupt handler function address in tick timer vector register...
|
/* Store interrupt handler function address in tick timer vector register...
|
||||||
The ISR installed depends on whether the preemptive or cooperative
|
* The ISR installed depends on whether the preemptive or cooperative
|
||||||
scheduler is being used. */
|
* scheduler is being used. */
|
||||||
#if configUSE_PREEMPTION == 1
|
#if configUSE_PREEMPTION == 1
|
||||||
{
|
{
|
||||||
extern void ( vPreemptiveTick )( void );
|
extern void( vPreemptiveTick )( void );
|
||||||
AT91C_BASE_AIC->AIC_SVR[portTIMER_AIC_CHANNEL] = ( uint32_t ) vPreemptiveTick;
|
AT91C_BASE_AIC->AIC_SVR[ portTIMER_AIC_CHANNEL ] = ( uint32_t ) vPreemptiveTick;
|
||||||
}
|
}
|
||||||
#else // else use cooperative scheduler
|
#else // else use cooperative scheduler
|
||||||
{
|
{
|
||||||
extern void ( vNonPreemptiveTick )( void );
|
extern void( vNonPreemptiveTick )( void );
|
||||||
AT91C_BASE_AIC->AIC_SVR[portTIMER_AIC_CHANNEL] = ( uint32_t ) vNonPreemptiveTick;
|
AT91C_BASE_AIC->AIC_SVR[ portTIMER_AIC_CHANNEL ] = ( uint32_t ) vNonPreemptiveTick;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -209,27 +211,27 @@ volatile uint32_t ulDummy;
|
||||||
AT91C_BASE_AIC->AIC_SMR[ portTIMER_AIC_CHANNEL ] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | portTICK_PRIORITY_6;
|
AT91C_BASE_AIC->AIC_SMR[ portTIMER_AIC_CHANNEL ] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | portTICK_PRIORITY_6;
|
||||||
|
|
||||||
/* Enable the tick timer interrupt...
|
/* Enable the tick timer interrupt...
|
||||||
|
*
|
||||||
First at timer level */
|
* First at timer level */
|
||||||
portTIMER_REG_BASE_PTR->TC_IER = TC_CPCS;
|
portTIMER_REG_BASE_PTR->TC_IER = TC_CPCS;
|
||||||
|
|
||||||
/* Then at the AIC level. */
|
/* Then at the AIC level. */
|
||||||
AT91C_BASE_AIC->AIC_IECR = (1 << portTIMER_AIC_CHANNEL);
|
AT91C_BASE_AIC->AIC_IECR = ( 1 << portTIMER_AIC_CHANNEL );
|
||||||
|
|
||||||
/* Calculate timer compare value to achieve the desired tick rate... */
|
/* Calculate timer compare value to achieve the desired tick rate... */
|
||||||
if( (configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 2) ) <= 0xFFFF )
|
if( ( configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 2 ) ) <= 0xFFFF )
|
||||||
{
|
{
|
||||||
/* The tick rate is fast enough for us to use the faster timer input
|
/* The tick rate is fast enough for us to use the faster timer input
|
||||||
clock (main clock / 2). */
|
* clock (main clock / 2). */
|
||||||
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK2 | TC_BURST_NONE | TC_CPCTRG;
|
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK2 | TC_BURST_NONE | TC_CPCTRG;
|
||||||
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 2);
|
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 2 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We must use a slower timer input clock (main clock / 8) because the
|
/* We must use a slower timer input clock (main clock / 8) because the
|
||||||
tick rate is too slow for the faster input clock. */
|
* tick rate is too slow for the faster input clock. */
|
||||||
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK8 | TC_BURST_NONE | TC_CPCTRG;
|
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK8 | TC_BURST_NONE | TC_CPCTRG;
|
||||||
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 8);
|
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 8 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start tick timer... */
|
/* Start tick timer... */
|
||||||
|
|
|
@ -28,17 +28,17 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in port.c The ISR routines, which can only be compiled
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
* to ARM mode, are contained in this file.
|
* to ARM mode, are contained in this file.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V3.2.4
|
* Changes from V3.2.4
|
||||||
|
*
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
than each line having its own asm block.
|
+ than each line having its own asm block.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
|
@ -46,16 +46,16 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/* Constants required to handle interrupts. */
|
/* Constants required to handle interrupts. */
|
||||||
#define portCLEAR_AIC_INTERRUPT ( ( uint32_t ) 0 )
|
#define portCLEAR_AIC_INTERRUPT ( ( uint32_t ) 0 )
|
||||||
|
|
||||||
/* Constants required to handle critical sections. */
|
/* Constants required to handle critical sections. */
|
||||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||||
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
void vPortYieldProcessor( void ) __attribute__( ( interrupt( "SWI" ), naked ) );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
@ -67,7 +67,7 @@ void vPortISRStartFirstTask( void );
|
||||||
void vPortISRStartFirstTask( void )
|
void vPortISRStartFirstTask( void )
|
||||||
{
|
{
|
||||||
/* Simply start the scheduler. This is included here as it can only be
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
called from ARM mode. */
|
* called from ARM mode. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -83,8 +83,8 @@ void vPortISRStartFirstTask( void )
|
||||||
void vPortYieldProcessor( void )
|
void vPortYieldProcessor( void )
|
||||||
{
|
{
|
||||||
/* Within an IRQ ISR the link register has an offset from the true return
|
/* Within an IRQ ISR the link register has an offset from the true return
|
||||||
address, but an SWI ISR does not. Add the offset manually so the same
|
* address, but an SWI ISR does not. Add the offset manually so the same
|
||||||
ISR return code can be used in both cases. */
|
* ISR return code can be used in both cases. */
|
||||||
asm volatile ( "ADD LR, LR, #4" );
|
asm volatile ( "ADD LR, LR, #4" );
|
||||||
|
|
||||||
/* Perform the context switch. First save the context of the current task. */
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
|
@ -105,12 +105,12 @@ void vPortYieldProcessor( void )
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
simply increment the system tick. */
|
* simply increment the system tick. */
|
||||||
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
|
||||||
void vNonPreemptiveTick( void )
|
void vNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
static volatile uint32_t ulDummy;
|
static volatile uint32_t ulDummy;
|
||||||
|
|
||||||
/* Clear tick timer interrupt indication. */
|
/* Clear tick timer interrupt indication. */
|
||||||
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
||||||
|
@ -121,25 +121,25 @@ void vPortYieldProcessor( void )
|
||||||
AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;
|
AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* else preemption is turned on */
|
#else /* else preemption is turned on */
|
||||||
|
|
||||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||||
saved on entry as part of the context switch. */
|
* saved on entry as part of the context switch. */
|
||||||
void vPreemptiveTick( void ) __attribute__((naked));
|
void vPreemptiveTick( void ) __attribute__( ( naked ) );
|
||||||
void vPreemptiveTick( void )
|
void vPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the interrupted task. */
|
/* Save the context of the interrupted task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
/* WARNING - Do not use local (stack) variables here. Use globals
|
/* WARNING - Do not use local (stack) variables here. Use globals
|
||||||
if you must! */
|
* if you must! */
|
||||||
static volatile uint32_t ulDummy;
|
static volatile uint32_t ulDummy;
|
||||||
|
|
||||||
/* Clear tick timer interrupt indication. */
|
/* Clear tick timer interrupt indication. */
|
||||||
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
||||||
|
|
||||||
/* Increment the RTOS tick count, then look for the highest priority
|
/* Increment the RTOS tick count, then look for the highest priority
|
||||||
task that is ready to run. */
|
* task that is ready to run. */
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
{
|
{
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
|
@ -152,7 +152,7 @@ void vPortYieldProcessor( void )
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* if configUSE_PREEMPTION == 0 */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -163,50 +163,50 @@ void vPortYieldProcessor( void )
|
||||||
*/
|
*/
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void )
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
"BX R14" ); /* Return back to thumb. */
|
"BX R14" ); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void vPortEnableInterruptsFromThumb( void )
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
"BX R14" ); /* Return back to thumb. */
|
"BX R14" ); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
different optimisation levels. The interrupt flags can therefore not always
|
* different optimisation levels. The interrupt flags can therefore not always
|
||||||
be saved to the stack. Instead the critical section nesting level is stored
|
* be saved to the stack. Instead the critical section nesting level is stored
|
||||||
in a variable, which is then saved as part of the stack context. */
|
* in a variable, which is then saved as part of the stack context. */
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now that interrupts are disabled, ulCriticalNesting can be accessed
|
||||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
portENTER_CRITICAL() has been called. */
|
* portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,16 +218,16 @@ void vPortExitCritical( void )
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then interrupts should be
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
re-enabled. */
|
* re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,27 +27,27 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V3.2.3
|
* Changes from V3.2.3
|
||||||
|
*
|
||||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||||
|
+
|
||||||
Changes from V3.2.4
|
+ Changes from V3.2.4
|
||||||
|
+
|
||||||
+ Removed the use of the %0 parameter within the assembler macros and
|
+ Removed the use of the %0 parameter within the assembler macros and
|
||||||
replaced them with hard coded registers. This will ensure the
|
+ replaced them with hard coded registers. This will ensure the
|
||||||
assembler does not select the link register as the temp register as
|
+ assembler does not select the link register as the temp register as
|
||||||
was occasionally happening previously.
|
+ was occasionally happening previously.
|
||||||
|
+
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
than each line having its own asm block.
|
+ than each line having its own asm block.
|
||||||
|
+
|
||||||
Changes from V4.5.0
|
+ Changes from V4.5.0
|
||||||
|
+
|
||||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||||
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
+ and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||||
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
+ should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||||
macros as per the V4.5.1 demo code.
|
+ macros as per the V4.5.1 demo code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
@ -69,35 +69,35 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
||||||
#else
|
#else
|
||||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portYIELD() asm volatile ( "SWI 0" )
|
#define portYIELD() asm volatile ( "SWI 0" )
|
||||||
#define portNOP() asm volatile ( "NOP" )
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These define the timer to use for generating the tick interrupt.
|
* These define the timer to use for generating the tick interrupt.
|
||||||
|
@ -118,90 +118,90 @@ typedef unsigned long UBaseType_t;
|
||||||
* THUMB mode code will result in a compile time error.
|
* THUMB mode code will result in a compile time error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Set the LR to the task stack. */ \
|
/* Set the LR to the task stack. */ \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"LDR R0, =pxCurrentTCB \n\t" \
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t" \
|
||||||
"LDR LR, [R0] \n\t" \
|
"LDR LR, [R0] \n\t" \
|
||||||
\
|
\
|
||||||
/* The critical nesting depth is the first item on the stack. */ \
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
/* Load it into the ulCriticalNesting variable. */ \
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
"LDR R0, =ulCriticalNesting \n\t" \
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
"LDMFD LR!, {R1} \n\t" \
|
"LDMFD LR!, {R1} \n\t" \
|
||||||
"STR R1, [R0] \n\t" \
|
"STR R1, [R0] \n\t" \
|
||||||
\
|
\
|
||||||
/* Get the SPSR from the stack. */ \
|
/* Get the SPSR from the stack. */ \
|
||||||
"LDMFD LR!, {R0} \n\t" \
|
"LDMFD LR!, {R0} \n\t" \
|
||||||
"MSR SPSR, R0 \n\t" \
|
"MSR SPSR, R0 \n\t" \
|
||||||
\
|
\
|
||||||
/* Restore all system mode registers for the task. */ \
|
/* Restore all system mode registers for the task. */ \
|
||||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||||
"NOP \n\t" \
|
"NOP \n\t" \
|
||||||
\
|
\
|
||||||
/* Restore the return address. */ \
|
/* Restore the return address. */ \
|
||||||
"LDR LR, [LR, #+60] \n\t" \
|
"LDR LR, [LR, #+60] \n\t" \
|
||||||
\
|
\
|
||||||
/* And return - correcting the offset in the LR to obtain the */ \
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
/* correct address. */ \
|
/* correct address. */ \
|
||||||
"SUBS PC, LR, #4 \n\t" \
|
"SUBS PC, LR, #4 \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Push R0 as we are going to use the register. */ \
|
/* Push R0 as we are going to use the register. */ \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" \
|
"STMDB SP!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Set R0 to point to the task stack pointer. */ \
|
/* Set R0 to point to the task stack pointer. */ \
|
||||||
"STMDB SP,{SP}^ \n\t" \
|
"STMDB SP,{SP}^ \n\t" \
|
||||||
"NOP \n\t" \
|
"NOP \n\t" \
|
||||||
"SUB SP, SP, #4 \n\t" \
|
"SUB SP, SP, #4 \n\t" \
|
||||||
"LDMIA SP!,{R0} \n\t" \
|
"LDMIA SP!,{R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Push the return address onto the stack. */ \
|
/* Push the return address onto the stack. */ \
|
||||||
"STMDB R0!, {LR} \n\t" \
|
"STMDB R0!, {LR} \n\t" \
|
||||||
\
|
\
|
||||||
/* Now we have saved LR we can use it instead of R0. */ \
|
/* Now we have saved LR we can use it instead of R0. */ \
|
||||||
"MOV LR, R0 \n\t" \
|
"MOV LR, R0 \n\t" \
|
||||||
\
|
\
|
||||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||||
"LDMIA SP!, {R0} \n\t" \
|
"LDMIA SP!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Push all the system mode registers onto the task stack. */ \
|
/* Push all the system mode registers onto the task stack. */ \
|
||||||
"STMDB LR,{R0-LR}^ \n\t" \
|
"STMDB LR,{R0-LR}^ \n\t" \
|
||||||
"NOP \n\t" \
|
"NOP \n\t" \
|
||||||
"SUB LR, LR, #60 \n\t" \
|
"SUB LR, LR, #60 \n\t" \
|
||||||
\
|
\
|
||||||
/* Push the SPSR onto the task stack. */ \
|
/* Push the SPSR onto the task stack. */ \
|
||||||
"MRS R0, SPSR \n\t" \
|
"MRS R0, SPSR \n\t" \
|
||||||
"STMDB LR!, {R0} \n\t" \
|
"STMDB LR!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
"LDR R0, =ulCriticalNesting \n\t" \
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t" \
|
||||||
"STMDB LR!, {R0} \n\t" \
|
"STMDB LR!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Store the new top of stack for the task. */ \
|
/* Store the new top of stack for the task. */ \
|
||||||
"LDR R0, =pxCurrentTCB \n\t" \
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t" \
|
||||||
"STR LR, [R0] \n\t" \
|
"STR LR, [R0] \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
|
|
||||||
/* Critical section handling. */
|
/* Critical section handling. */
|
||||||
|
|
||||||
|
@ -214,43 +214,43 @@ extern volatile uint32_t ulCriticalNesting; \
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,50 +1,50 @@
|
||||||
//* ----------------------------------------------------------------------------
|
/** ---------------------------------------------------------------------------- */
|
||||||
//* ATMEL Microcontroller Software Support - ROUSSET -
|
/** ATMEL Microcontroller Software Support - ROUSSET - */
|
||||||
//* ----------------------------------------------------------------------------
|
/** ---------------------------------------------------------------------------- */
|
||||||
//* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
/** DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */
|
||||||
//* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
/** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
|
||||||
//* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
/** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */
|
||||||
//* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
/** DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */
|
||||||
//* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
/** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
|
||||||
//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
/** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
|
||||||
//* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
/** OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
|
||||||
//* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
/** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
|
||||||
//* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
/** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
|
||||||
//* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
/** EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
||||||
//* ----------------------------------------------------------------------------
|
/** ---------------------------------------------------------------------------- */
|
||||||
//* File Name : lib_AT91SAM7X256.h
|
/** File Name : lib_AT91SAM7X256.h */
|
||||||
//* Object : AT91SAM7X256 inlined functions
|
/** Object : AT91SAM7X256 inlined functions */
|
||||||
//* Generated : AT91 SW Application Group 05/20/2005 (16:22:29)
|
/** Generated : AT91 SW Application Group 05/20/2005 (16:22:29) */
|
||||||
//*
|
/** */
|
||||||
//* CVS Reference : /lib_dbgu.h/1.1/Fri Jan 31 12:18:40 2003//
|
/** CVS Reference : /lib_dbgu.h/1.1/Fri Jan 31 12:18:40 2003// */
|
||||||
//* CVS Reference : /lib_pmc_SAM7X.h/1.1/Tue Feb 1 08:32:10 2005//
|
/** CVS Reference : /lib_pmc_SAM7X.h/1.1/Tue Feb 1 08:32:10 2005// */
|
||||||
//* CVS Reference : /lib_VREG_6085B.h/1.1/Tue Feb 1 16:20:47 2005//
|
/** CVS Reference : /lib_VREG_6085B.h/1.1/Tue Feb 1 16:20:47 2005// */
|
||||||
//* CVS Reference : /lib_rstc_6098A.h/1.1/Wed Oct 6 10:39:20 2004//
|
/** CVS Reference : /lib_rstc_6098A.h/1.1/Wed Oct 6 10:39:20 2004// */
|
||||||
//* CVS Reference : /lib_ssc.h/1.4/Fri Jan 31 12:19:20 2003//
|
/** CVS Reference : /lib_ssc.h/1.4/Fri Jan 31 12:19:20 2003// */
|
||||||
//* CVS Reference : /lib_wdtc_6080A.h/1.1/Wed Oct 6 10:38:30 2004//
|
/** CVS Reference : /lib_wdtc_6080A.h/1.1/Wed Oct 6 10:38:30 2004// */
|
||||||
//* CVS Reference : /lib_usart.h/1.5/Thu Nov 21 16:01:54 2002//
|
/** CVS Reference : /lib_usart.h/1.5/Thu Nov 21 16:01:54 2002// */
|
||||||
//* CVS Reference : /lib_spi2.h/1.1/Mon Aug 25 14:23:52 2003//
|
/** CVS Reference : /lib_spi2.h/1.1/Mon Aug 25 14:23:52 2003// */
|
||||||
//* CVS Reference : /lib_pitc_6079A.h/1.2/Tue Nov 9 14:43:56 2004//
|
/** CVS Reference : /lib_pitc_6079A.h/1.2/Tue Nov 9 14:43:56 2004// */
|
||||||
//* CVS Reference : /lib_aic_6075b.h/1.1/Fri May 20 14:01:19 2005//
|
/** CVS Reference : /lib_aic_6075b.h/1.1/Fri May 20 14:01:19 2005// */
|
||||||
//* CVS Reference : /lib_aes_6149a.h/1.1/Mon Jan 17 07:43:09 2005//
|
/** CVS Reference : /lib_aes_6149a.h/1.1/Mon Jan 17 07:43:09 2005// */
|
||||||
//* CVS Reference : /lib_twi.h/1.3/Mon Jul 19 14:27:58 2004//
|
/** CVS Reference : /lib_twi.h/1.3/Mon Jul 19 14:27:58 2004// */
|
||||||
//* CVS Reference : /lib_adc.h/1.6/Fri Oct 17 09:12:38 2003//
|
/** CVS Reference : /lib_adc.h/1.6/Fri Oct 17 09:12:38 2003// */
|
||||||
//* CVS Reference : /lib_rttc_6081A.h/1.1/Wed Oct 6 10:39:38 2004//
|
/** CVS Reference : /lib_rttc_6081A.h/1.1/Wed Oct 6 10:39:38 2004// */
|
||||||
//* CVS Reference : /lib_udp.h/1.4/Wed Feb 16 08:39:34 2005//
|
/** CVS Reference : /lib_udp.h/1.4/Wed Feb 16 08:39:34 2005// */
|
||||||
//* CVS Reference : /lib_des3_6150a.h/1.1/Mon Jan 17 09:19:19 2005//
|
/** CVS Reference : /lib_des3_6150a.h/1.1/Mon Jan 17 09:19:19 2005// */
|
||||||
//* CVS Reference : /lib_tc_1753b.h/1.1/Fri Jan 31 12:20:02 2003//
|
/** CVS Reference : /lib_tc_1753b.h/1.1/Fri Jan 31 12:20:02 2003// */
|
||||||
//* CVS Reference : /lib_MC_SAM7X.h/1.1/Thu Mar 25 15:19:14 2004//
|
/** CVS Reference : /lib_MC_SAM7X.h/1.1/Thu Mar 25 15:19:14 2004// */
|
||||||
//* CVS Reference : /lib_pio.h/1.3/Fri Jan 31 12:18:56 2003//
|
/** CVS Reference : /lib_pio.h/1.3/Fri Jan 31 12:18:56 2003// */
|
||||||
//* CVS Reference : /lib_can_AT91.h/1.4/Fri Oct 17 09:12:50 2003//
|
/** CVS Reference : /lib_can_AT91.h/1.4/Fri Oct 17 09:12:50 2003// */
|
||||||
//* CVS Reference : /lib_PWM_SAM.h/1.3/Thu Jan 22 10:10:50 2004//
|
/** CVS Reference : /lib_PWM_SAM.h/1.3/Thu Jan 22 10:10:50 2004// */
|
||||||
//* CVS Reference : /lib_pdc.h/1.2/Tue Jul 2 13:29:40 2002//
|
/** CVS Reference : /lib_pdc.h/1.2/Tue Jul 2 13:29:40 2002// */
|
||||||
//* ----------------------------------------------------------------------------
|
/** ---------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
#include "AT91SAM7X256.h"
|
#include "AT91SAM7X256.h"
|
||||||
|
|
||||||
|
|
||||||
//*----------------------------------------------------------------------------
|
/**---------------------------------------------------------------------------- */
|
||||||
//* \fn AT91F_AIC_ConfigureIt
|
/** \fn AT91F_AIC_ConfigureIt */
|
||||||
//* \brief Interrupt Handler Initialization
|
/** \brief Interrupt Handler Initialization */
|
||||||
//*----------------------------------------------------------------------------
|
/**---------------------------------------------------------------------------- */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -28,12 +28,12 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||||
*
|
*
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in this file. The ISR routines, which can only be compiled
|
* contained in this file. The ISR routines, which can only be compiled
|
||||||
* to ARM mode are contained in portISR.c.
|
* to ARM mode are contained in portISR.c.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -46,24 +46,24 @@
|
||||||
#include "AT91SAM7X256.h"
|
#include "AT91SAM7X256.h"
|
||||||
|
|
||||||
/* Constants required to setup the task context. */
|
/* Constants required to setup the task context. */
|
||||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
||||||
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
||||||
|
|
||||||
/* Constants required to setup the tick ISR. */
|
/* Constants required to setup the tick ISR. */
|
||||||
#define portENABLE_TIMER ( ( uint8_t ) 0x01 )
|
#define portENABLE_TIMER ( ( uint8_t ) 0x01 )
|
||||||
#define portPRESCALE_VALUE 0x00
|
#define portPRESCALE_VALUE 0x00
|
||||||
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
|
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
|
||||||
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
|
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
|
||||||
|
|
||||||
/* Constants required to setup the PIT. */
|
/* Constants required to setup the PIT. */
|
||||||
#define portPIT_CLOCK_DIVISOR ( ( uint32_t ) 16 )
|
#define portPIT_CLOCK_DIVISOR ( ( uint32_t ) 16 )
|
||||||
#define portPIT_COUNTER_VALUE ( ( ( configCPU_CLOCK_HZ / portPIT_CLOCK_DIVISOR ) / 1000UL ) * portTICK_PERIOD_MS )
|
#define portPIT_COUNTER_VALUE ( ( ( configCPU_CLOCK_HZ / portPIT_CLOCK_DIVISOR ) / 1000UL ) * portTICK_PERIOD_MS )
|
||||||
|
|
||||||
#define portINT_LEVEL_SENSITIVE 0
|
#define portINT_LEVEL_SENSITIVE 0
|
||||||
#define portPIT_ENABLE ( ( uint16_t ) 0x1 << 24 )
|
#define portPIT_ENABLE ( ( uint16_t ) 0x1 << 24 )
|
||||||
#define portPIT_INT_ENABLE ( ( uint16_t ) 0x1 << 25 )
|
#define portPIT_INT_ENABLE ( ( uint16_t ) 0x1 << 25 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Setup the timer to generate the tick interrupts. */
|
/* Setup the timer to generate the tick interrupts. */
|
||||||
|
@ -83,61 +83,63 @@ extern void vPortISRStartFirstTask( void );
|
||||||
*
|
*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
StackType_t *pxOriginalTOS;
|
StackType_t * pxOriginalTOS;
|
||||||
|
|
||||||
pxOriginalTOS = pxTopOfStack;
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
is not really required. */
|
* is not really required. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro. */
|
* expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First on the stack is the return address - which in this case is the
|
/* First on the stack is the return address - which in this case is the
|
||||||
start of the task. The offset is added to make the return address appear
|
* start of the task. The offset is added to make the return address appear
|
||||||
as it would within an IRQ ISR. */
|
* as it would within an IRQ ISR. */
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */
|
*pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* When the task starts is will expect to find the function parameter in
|
/* When the task starts is will expect to find the function parameter in
|
||||||
R0. */
|
* R0. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The last thing onto the stack is the status register, which is set for
|
/* The last thing onto the stack is the status register, which is set for
|
||||||
system mode, with interrupts enabled. */
|
* system mode, with interrupts enabled. */
|
||||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
@ -150,9 +152,9 @@ StackType_t *pxOriginalTOS;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Some optimisation levels use the stack differently to others. This
|
/* Some optimisation levels use the stack differently to others. This
|
||||||
means the interrupt flags cannot always be stored on the stack and will
|
* means the interrupt flags cannot always be stored on the stack and will
|
||||||
instead be stored in a variable, which is then saved as part of the
|
* instead be stored in a variable, which is then saved as part of the
|
||||||
tasks context. */
|
* tasks context. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -162,7 +164,7 @@ StackType_t *pxOriginalTOS;
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
here already. */
|
* here already. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
|
@ -176,7 +178,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the ARM port will require this function as there
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
is nothing to return to. */
|
* is nothing to return to. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -185,27 +187,23 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
AT91PS_PITC pxPIT = AT91C_BASE_PITC;
|
AT91PS_PITC pxPIT = AT91C_BASE_PITC;
|
||||||
|
|
||||||
/* Setup the AIC for PIT interrupts. The interrupt routine chosen depends
|
/* Setup the AIC for PIT interrupts. The interrupt routine chosen depends
|
||||||
on whether the preemptive or cooperative scheduler is being used. */
|
* on whether the preemptive or cooperative scheduler is being used. */
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
extern void( vNonPreemptiveTick ) ( void );
|
||||||
extern void ( vNonPreemptiveTick ) ( void );
|
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void ( * )( void ) )vNonPreemptiveTick );
|
||||||
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vNonPreemptiveTick );
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
extern void( vPreemptiveTick )( void );
|
||||||
extern void ( vPreemptiveTick )( void );
|
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void ( * )( void ) )vPreemptiveTick );
|
||||||
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vPreemptiveTick );
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configure the PIT period. */
|
/* Configure the PIT period. */
|
||||||
pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
|
pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
|
||||||
|
|
||||||
/* Enable the interrupt. Global interrupts are disabled at this point so
|
/* Enable the interrupt. Global interrupts are disabled at this point so
|
||||||
this is safe. */
|
* this is safe. */
|
||||||
AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS;
|
AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
@ -28,17 +28,17 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in port.c The ISR routines, which can only be compiled
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
* to ARM mode, are contained in this file.
|
* to ARM mode, are contained in this file.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V3.2.4
|
* Changes from V3.2.4
|
||||||
|
*
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
than each line having its own asm block.
|
+ than each line having its own asm block.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
@ -47,17 +47,17 @@
|
||||||
#include "AT91SAM7X256.h"
|
#include "AT91SAM7X256.h"
|
||||||
|
|
||||||
/* Constants required to handle interrupts. */
|
/* Constants required to handle interrupts. */
|
||||||
#define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 )
|
#define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 )
|
||||||
#define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 )
|
#define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 )
|
||||||
|
|
||||||
/* Constants required to handle critical sections. */
|
/* Constants required to handle critical sections. */
|
||||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||||
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
void vPortYieldProcessor( void ) __attribute__( ( interrupt( "SWI" ), naked ) );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
@ -69,7 +69,7 @@ void vPortISRStartFirstTask( void );
|
||||||
void vPortISRStartFirstTask( void )
|
void vPortISRStartFirstTask( void )
|
||||||
{
|
{
|
||||||
/* Simply start the scheduler. This is included here as it can only be
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
called from ARM mode. */
|
* called from ARM mode. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -85,8 +85,8 @@ void vPortISRStartFirstTask( void )
|
||||||
void vPortYieldProcessor( void )
|
void vPortYieldProcessor( void )
|
||||||
{
|
{
|
||||||
/* Within an IRQ ISR the link register has an offset from the true return
|
/* Within an IRQ ISR the link register has an offset from the true return
|
||||||
address, but an SWI ISR does not. Add the offset manually so the same
|
* address, but an SWI ISR does not. Add the offset manually so the same
|
||||||
ISR return code can be used in both cases. */
|
* ISR return code can be used in both cases. */
|
||||||
__asm volatile ( "ADD LR, LR, #4" );
|
__asm volatile ( "ADD LR, LR, #4" );
|
||||||
|
|
||||||
/* Perform the context switch. First save the context of the current task. */
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
|
@ -107,16 +107,16 @@ void vPortYieldProcessor( void )
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
simply increment the system tick. */
|
* simply increment the system tick. */
|
||||||
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
|
||||||
void vNonPreemptiveTick( void )
|
void vNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
uint32_t ulDummy;
|
uint32_t ulDummy;
|
||||||
|
|
||||||
/* Increment the tick count - which may wake some tasks but as the
|
/* Increment the tick count - which may wake some tasks but as the
|
||||||
preemptive scheduler is not being used any woken task is not given
|
* preemptive scheduler is not being used any woken task is not given
|
||||||
processor time no matter what its priority. */
|
* processor time no matter what its priority. */
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
|
|
||||||
/* Clear the PIT interrupt. */
|
/* Clear the PIT interrupt. */
|
||||||
|
@ -126,11 +126,11 @@ void vPortYieldProcessor( void )
|
||||||
AT91C_BASE_AIC->AIC_EOICR = ulDummy;
|
AT91C_BASE_AIC->AIC_EOICR = ulDummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else /* if configUSE_PREEMPTION == 0 */
|
||||||
|
|
||||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||||
saved on entry as part of the context switch. */
|
* saved on entry as part of the context switch. */
|
||||||
void vPreemptiveTick( void ) __attribute__((naked));
|
void vPreemptiveTick( void ) __attribute__( ( naked ) );
|
||||||
void vPreemptiveTick( void )
|
void vPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the current task. */
|
/* Save the context of the current task. */
|
||||||
|
@ -149,7 +149,7 @@ void vPortYieldProcessor( void )
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* if configUSE_PREEMPTION == 0 */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -158,49 +158,49 @@ void vPortYieldProcessor( void )
|
||||||
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
|
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
|
||||||
* the utilities are defined as macros in portmacro.h - as per other ports.
|
* the utilities are defined as macros in portmacro.h - as per other ports.
|
||||||
*/
|
*/
|
||||||
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void )
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
"BX R14" ); /* Return back to thumb. */
|
"BX R14" ); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void vPortEnableInterruptsFromThumb( void )
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
"BX R14" ); /* Return back to thumb. */
|
"BX R14" ); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
different optimisation levels. The interrupt flags can therefore not always
|
* different optimisation levels. The interrupt flags can therefore not always
|
||||||
be saved to the stack. Instead the critical section nesting level is stored
|
* be saved to the stack. Instead the critical section nesting level is stored
|
||||||
in a variable, which is then saved as part of the stack context. */
|
* in a variable, which is then saved as part of the stack context. */
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now that interrupts are disabled, ulCriticalNesting can be accessed
|
||||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
portENTER_CRITICAL() has been called. */
|
* portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,16 +212,16 @@ void vPortExitCritical( void )
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then interrupts should be
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
re-enabled. */
|
* re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,27 +27,27 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V3.2.3
|
* Changes from V3.2.3
|
||||||
|
*
|
||||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||||
|
+
|
||||||
Changes from V3.2.4
|
+ Changes from V3.2.4
|
||||||
|
+
|
||||||
+ Removed the use of the %0 parameter within the assembler macros and
|
+ Removed the use of the %0 parameter within the assembler macros and
|
||||||
replaced them with hard coded registers. This will ensure the
|
+ replaced them with hard coded registers. This will ensure the
|
||||||
assembler does not select the link register as the temp register as
|
+ assembler does not select the link register as the temp register as
|
||||||
was occasionally happening previously.
|
+ was occasionally happening previously.
|
||||||
|
+
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
than each line having its own asm block.
|
+ than each line having its own asm block.
|
||||||
|
+
|
||||||
Changes from V4.5.0
|
+ Changes from V4.5.0
|
||||||
|
+
|
||||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||||
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
+ and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||||
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
+ should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||||
macros as per the V4.5.1 demo code.
|
+ macros as per the V4.5.1 demo code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
@ -69,34 +69,34 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE portLONG
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
||||||
#else
|
#else
|
||||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP() __asm volatile ( "NOP" );
|
#define portNOP() __asm volatile ( "NOP" );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,92 +109,92 @@ typedef unsigned long UBaseType_t;
|
||||||
* THUMB mode code will result in a compile time error.
|
* THUMB mode code will result in a compile time error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Set the LR to the task stack. */ \
|
/* Set the LR to the task stack. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"LDR R0, =pxCurrentTCB \n\t" \
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t" \
|
||||||
"LDR LR, [R0] \n\t" \
|
"LDR LR, [R0] \n\t" \
|
||||||
\
|
\
|
||||||
/* The critical nesting depth is the first item on the stack. */ \
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
/* Load it into the ulCriticalNesting variable. */ \
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
"LDR R0, =ulCriticalNesting \n\t" \
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
"LDMFD LR!, {R1} \n\t" \
|
"LDMFD LR!, {R1} \n\t" \
|
||||||
"STR R1, [R0] \n\t" \
|
"STR R1, [R0] \n\t" \
|
||||||
\
|
\
|
||||||
/* Get the SPSR from the stack. */ \
|
/* Get the SPSR from the stack. */ \
|
||||||
"LDMFD LR!, {R0} \n\t" \
|
"LDMFD LR!, {R0} \n\t" \
|
||||||
"MSR SPSR, R0 \n\t" \
|
"MSR SPSR, R0 \n\t" \
|
||||||
\
|
\
|
||||||
/* Restore all system mode registers for the task. */ \
|
/* Restore all system mode registers for the task. */ \
|
||||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||||
"NOP \n\t" \
|
"NOP \n\t" \
|
||||||
\
|
\
|
||||||
/* Restore the return address. */ \
|
/* Restore the return address. */ \
|
||||||
"LDR LR, [LR, #+60] \n\t" \
|
"LDR LR, [LR, #+60] \n\t" \
|
||||||
\
|
\
|
||||||
/* And return - correcting the offset in the LR to obtain the */ \
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
/* correct address. */ \
|
/* correct address. */ \
|
||||||
"SUBS PC, LR, #4 \n\t" \
|
"SUBS PC, LR, #4 \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Push R0 as we are going to use the register. */ \
|
/* Push R0 as we are going to use the register. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" \
|
"STMDB SP!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Set R0 to point to the task stack pointer. */ \
|
/* Set R0 to point to the task stack pointer. */ \
|
||||||
"STMDB SP,{SP}^ \n\t" \
|
"STMDB SP,{SP}^ \n\t" \
|
||||||
"NOP \n\t" \
|
"NOP \n\t" \
|
||||||
"SUB SP, SP, #4 \n\t" \
|
"SUB SP, SP, #4 \n\t" \
|
||||||
"LDMIA SP!,{R0} \n\t" \
|
"LDMIA SP!,{R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Push the return address onto the stack. */ \
|
/* Push the return address onto the stack. */ \
|
||||||
"STMDB R0!, {LR} \n\t" \
|
"STMDB R0!, {LR} \n\t" \
|
||||||
\
|
\
|
||||||
/* Now we have saved LR we can use it instead of R0. */ \
|
/* Now we have saved LR we can use it instead of R0. */ \
|
||||||
"MOV LR, R0 \n\t" \
|
"MOV LR, R0 \n\t" \
|
||||||
\
|
\
|
||||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||||
"LDMIA SP!, {R0} \n\t" \
|
"LDMIA SP!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Push all the system mode registers onto the task stack. */ \
|
/* Push all the system mode registers onto the task stack. */ \
|
||||||
"STMDB LR,{R0-LR}^ \n\t" \
|
"STMDB LR,{R0-LR}^ \n\t" \
|
||||||
"NOP \n\t" \
|
"NOP \n\t" \
|
||||||
"SUB LR, LR, #60 \n\t" \
|
"SUB LR, LR, #60 \n\t" \
|
||||||
\
|
\
|
||||||
/* Push the SPSR onto the task stack. */ \
|
/* Push the SPSR onto the task stack. */ \
|
||||||
"MRS R0, SPSR \n\t" \
|
"MRS R0, SPSR \n\t" \
|
||||||
"STMDB LR!, {R0} \n\t" \
|
"STMDB LR!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
"LDR R0, =ulCriticalNesting \n\t" \
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t" \
|
||||||
"STMDB LR!, {R0} \n\t" \
|
"STMDB LR!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Store the new top of stack for the task. */ \
|
/* Store the new top of stack for the task. */ \
|
||||||
"LDR R0, =pxCurrentTCB \n\t" \
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t" \
|
||||||
"STR LR, [R0] \n\t" \
|
"STR LR, [R0] \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -209,42 +209,42 @@ extern volatile uint32_t ulCriticalNesting; \
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -28,12 +28,12 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||||
*
|
*
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in this file. The ISR routines, which can only be compiled
|
* contained in this file. The ISR routines, which can only be compiled
|
||||||
* to ARM mode are contained in portISR.c.
|
* to ARM mode are contained in portISR.c.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
|
@ -44,21 +44,21 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/* Constants required to setup the task context. */
|
/* Constants required to setup the task context. */
|
||||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
||||||
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
||||||
|
|
||||||
/* Constants required to setup the tick ISR. */
|
/* Constants required to setup the tick ISR. */
|
||||||
#define portENABLE_TIMER ( ( uint8_t ) 0x01 )
|
#define portENABLE_TIMER ( ( uint8_t ) 0x01 )
|
||||||
#define portPRESCALE_VALUE 0x00
|
#define portPRESCALE_VALUE 0x00
|
||||||
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
|
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
|
||||||
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
|
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
|
||||||
|
|
||||||
/* Constants required to setup the VIC for the tick ISR. */
|
/* Constants required to setup the VIC for the tick ISR. */
|
||||||
#define portTIMER_VIC_CHANNEL ( ( uint32_t ) 0x0004 )
|
#define portTIMER_VIC_CHANNEL ( ( uint32_t ) 0x0004 )
|
||||||
#define portTIMER_VIC_CHANNEL_BIT ( ( uint32_t ) 0x0010 )
|
#define portTIMER_VIC_CHANNEL_BIT ( ( uint32_t ) 0x0010 )
|
||||||
#define portTIMER_VIC_ENABLE ( ( uint32_t ) 0x0020 )
|
#define portTIMER_VIC_ENABLE ( ( uint32_t ) 0x0020 )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -79,61 +79,63 @@ extern void vPortISRStartFirstTask( void );
|
||||||
*
|
*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
StackType_t *pxOriginalTOS;
|
StackType_t * pxOriginalTOS;
|
||||||
|
|
||||||
pxOriginalTOS = pxTopOfStack;
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
is not really required. */
|
* is not really required. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro. */
|
* expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First on the stack is the return address - which in this case is the
|
/* First on the stack is the return address - which in this case is the
|
||||||
start of the task. The offset is added to make the return address appear
|
* start of the task. The offset is added to make the return address appear
|
||||||
as it would within an IRQ ISR. */
|
* as it would within an IRQ ISR. */
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
*pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */
|
*pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* When the task starts is will expect to find the function parameter in
|
/* When the task starts is will expect to find the function parameter in
|
||||||
R0. */
|
* R0. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The last thing onto the stack is the status register, which is set for
|
/* The last thing onto the stack is the status register, which is set for
|
||||||
system mode, with interrupts enabled. */
|
* system mode, with interrupts enabled. */
|
||||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||||
|
|
||||||
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
||||||
|
@ -145,9 +147,9 @@ StackType_t *pxOriginalTOS;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Some optimisation levels use the stack differently to others. This
|
/* Some optimisation levels use the stack differently to others. This
|
||||||
means the interrupt flags cannot always be stored on the stack and will
|
* means the interrupt flags cannot always be stored on the stack and will
|
||||||
instead be stored in a variable, which is then saved as part of the
|
* instead be stored in a variable, which is then saved as part of the
|
||||||
tasks context. */
|
* tasks context. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -157,7 +159,7 @@ StackType_t *pxOriginalTOS;
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
here already. */
|
* here already. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
|
@ -171,7 +173,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the ARM port will require this function as there
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
is nothing to return to. */
|
* is nothing to return to. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -180,18 +182,19 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
uint32_t ulCompareMatch;
|
uint32_t ulCompareMatch;
|
||||||
extern void ( vTickISR )( void );
|
|
||||||
|
extern void( vTickISR )( void );
|
||||||
|
|
||||||
/* A 1ms tick does not require the use of the timer prescale. This is
|
/* A 1ms tick does not require the use of the timer prescale. This is
|
||||||
defaulted to zero but can be used if necessary. */
|
* defaulted to zero but can be used if necessary. */
|
||||||
T0_PR = portPRESCALE_VALUE;
|
T0_PR = portPRESCALE_VALUE;
|
||||||
|
|
||||||
/* Calculate the match value required for our wanted tick rate. */
|
/* Calculate the match value required for our wanted tick rate. */
|
||||||
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||||
|
|
||||||
/* Protect against divide by zero. Using an if() statement still results
|
/* Protect against divide by zero. Using an if() statement still results
|
||||||
in a warning - hence the #if. */
|
* in a warning - hence the #if. */
|
||||||
#if portPRESCALE_VALUE != 0
|
#if portPRESCALE_VALUE != 0
|
||||||
{
|
{
|
||||||
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
||||||
|
@ -207,13 +210,13 @@ extern void ( vTickISR )( void );
|
||||||
VICIntEnable |= portTIMER_VIC_CHANNEL_BIT;
|
VICIntEnable |= portTIMER_VIC_CHANNEL_BIT;
|
||||||
|
|
||||||
/* The ISR installed depends on whether the preemptive or cooperative
|
/* The ISR installed depends on whether the preemptive or cooperative
|
||||||
scheduler is being used. */
|
* scheduler is being used. */
|
||||||
|
|
||||||
VICVectAddr0 = ( int32_t ) vTickISR;
|
VICVectAddr0 = ( int32_t ) vTickISR;
|
||||||
VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE;
|
VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE;
|
||||||
|
|
||||||
/* Start the timer - interrupts are disabled when this function is called
|
/* Start the timer - interrupts are disabled when this function is called
|
||||||
so it is okay to do this here. */
|
* so it is okay to do this here. */
|
||||||
T0_TCR = portENABLE_TIMER;
|
T0_TCR = portENABLE_TIMER;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
@ -28,45 +28,45 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in port.c The ISR routines, which can only be compiled
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
* to ARM mode, are contained in this file.
|
* to ARM mode, are contained in this file.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V2.5.2
|
* Changes from V2.5.2
|
||||||
|
*
|
||||||
+ The critical section management functions have been changed. These no
|
+ The critical section management functions have been changed. These no
|
||||||
longer modify the stack and are safe to use at all optimisation levels.
|
+ longer modify the stack and are safe to use at all optimisation levels.
|
||||||
The functions are now also the same for both ARM and THUMB modes.
|
+ The functions are now also the same for both ARM and THUMB modes.
|
||||||
|
+
|
||||||
Changes from V2.6.0
|
+ Changes from V2.6.0
|
||||||
|
+
|
||||||
+ Removed the 'static' from the definition of vNonPreemptiveTick() to
|
+ Removed the 'static' from the definition of vNonPreemptiveTick() to
|
||||||
allow the demo to link when using the cooperative scheduler.
|
+ allow the demo to link when using the cooperative scheduler.
|
||||||
|
+
|
||||||
Changes from V3.2.4
|
+ Changes from V3.2.4
|
||||||
|
+
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
than each line having its own asm block.
|
+ than each line having its own asm block.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
|
||||||
/* Constants required to handle interrupts. */
|
/* Constants required to handle interrupts. */
|
||||||
#define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 )
|
#define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 )
|
||||||
#define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 )
|
#define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 )
|
||||||
|
|
||||||
/* Constants required to handle critical sections. */
|
/* Constants required to handle critical sections. */
|
||||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||||
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
void vPortYieldProcessor( void ) __attribute__( ( interrupt( "SWI" ), naked ) );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
@ -78,7 +78,7 @@ void vPortISRStartFirstTask( void );
|
||||||
void vPortISRStartFirstTask( void )
|
void vPortISRStartFirstTask( void )
|
||||||
{
|
{
|
||||||
/* Simply start the scheduler. This is included here as it can only be
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
called from ARM mode. */
|
* called from ARM mode. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -94,8 +94,8 @@ void vPortISRStartFirstTask( void )
|
||||||
void vPortYieldProcessor( void )
|
void vPortYieldProcessor( void )
|
||||||
{
|
{
|
||||||
/* Within an IRQ ISR the link register has an offset from the true return
|
/* Within an IRQ ISR the link register has an offset from the true return
|
||||||
address, but an SWI ISR does not. Add the offset manually so the same
|
* address, but an SWI ISR does not. Add the offset manually so the same
|
||||||
ISR return code can be used in both cases. */
|
* ISR return code can be used in both cases. */
|
||||||
__asm volatile ( "ADD LR, LR, #4" );
|
__asm volatile ( "ADD LR, LR, #4" );
|
||||||
|
|
||||||
/* Perform the context switch. First save the context of the current task. */
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
|
@ -112,14 +112,14 @@ void vPortYieldProcessor( void )
|
||||||
/*
|
/*
|
||||||
* The ISR used for the scheduler tick.
|
* The ISR used for the scheduler tick.
|
||||||
*/
|
*/
|
||||||
void vTickISR( void ) __attribute__((naked));
|
void vTickISR( void ) __attribute__( ( naked ) );
|
||||||
void vTickISR( void )
|
void vTickISR( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the interrupted task. */
|
/* Save the context of the interrupted task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
/* Increment the RTOS tick count, then look for the highest priority
|
/* Increment the RTOS tick count, then look for the highest priority
|
||||||
task that is ready to run. */
|
* task that is ready to run. */
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" bl xTaskIncrementTick \t\n" \
|
" bl xTaskIncrementTick \t\n" \
|
||||||
|
@ -146,50 +146,50 @@ void vTickISR( void )
|
||||||
*/
|
*/
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void )
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
"BX R14" ); /* Return back to thumb. */
|
"BX R14" ); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void vPortEnableInterruptsFromThumb( void )
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
"BX R14" ); /* Return back to thumb. */
|
"BX R14" ); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
different optimisation levels. The interrupt flags can therefore not always
|
* different optimisation levels. The interrupt flags can therefore not always
|
||||||
be saved to the stack. Instead the critical section nesting level is stored
|
* be saved to the stack. Instead the critical section nesting level is stored
|
||||||
in a variable, which is then saved as part of the stack context. */
|
* in a variable, which is then saved as part of the stack context. */
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now that interrupts are disabled, ulCriticalNesting can be accessed
|
||||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
portENTER_CRITICAL() has been called. */
|
* portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,16 +201,16 @@ void vPortExitCritical( void )
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then interrupts should be
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
re-enabled. */
|
* re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,34 +46,34 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE portLONG
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
||||||
#else
|
#else
|
||||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP() __asm volatile ( "NOP" );
|
#define portNOP() __asm volatile ( "NOP" );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,92 +86,92 @@ typedef unsigned long UBaseType_t;
|
||||||
* THUMB mode code will result in a compile time error.
|
* THUMB mode code will result in a compile time error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Set the LR to the task stack. */ \
|
/* Set the LR to the task stack. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"LDR R0, =pxCurrentTCB \n\t" \
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t" \
|
||||||
"LDR LR, [R0] \n\t" \
|
"LDR LR, [R0] \n\t" \
|
||||||
\
|
\
|
||||||
/* The critical nesting depth is the first item on the stack. */ \
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
/* Load it into the ulCriticalNesting variable. */ \
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
"LDR R0, =ulCriticalNesting \n\t" \
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
"LDMFD LR!, {R1} \n\t" \
|
"LDMFD LR!, {R1} \n\t" \
|
||||||
"STR R1, [R0] \n\t" \
|
"STR R1, [R0] \n\t" \
|
||||||
\
|
\
|
||||||
/* Get the SPSR from the stack. */ \
|
/* Get the SPSR from the stack. */ \
|
||||||
"LDMFD LR!, {R0} \n\t" \
|
"LDMFD LR!, {R0} \n\t" \
|
||||||
"MSR SPSR, R0 \n\t" \
|
"MSR SPSR, R0 \n\t" \
|
||||||
\
|
\
|
||||||
/* Restore all system mode registers for the task. */ \
|
/* Restore all system mode registers for the task. */ \
|
||||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||||
"NOP \n\t" \
|
"NOP \n\t" \
|
||||||
\
|
\
|
||||||
/* Restore the return address. */ \
|
/* Restore the return address. */ \
|
||||||
"LDR LR, [LR, #+60] \n\t" \
|
"LDR LR, [LR, #+60] \n\t" \
|
||||||
\
|
\
|
||||||
/* And return - correcting the offset in the LR to obtain the */ \
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
/* correct address. */ \
|
/* correct address. */ \
|
||||||
"SUBS PC, LR, #4 \n\t" \
|
"SUBS PC, LR, #4 \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Push R0 as we are going to use the register. */ \
|
/* Push R0 as we are going to use the register. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" \
|
"STMDB SP!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Set R0 to point to the task stack pointer. */ \
|
/* Set R0 to point to the task stack pointer. */ \
|
||||||
"STMDB SP,{SP}^ \n\t" \
|
"STMDB SP,{SP}^ \n\t" \
|
||||||
"NOP \n\t" \
|
"NOP \n\t" \
|
||||||
"SUB SP, SP, #4 \n\t" \
|
"SUB SP, SP, #4 \n\t" \
|
||||||
"LDMIA SP!,{R0} \n\t" \
|
"LDMIA SP!,{R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Push the return address onto the stack. */ \
|
/* Push the return address onto the stack. */ \
|
||||||
"STMDB R0!, {LR} \n\t" \
|
"STMDB R0!, {LR} \n\t" \
|
||||||
\
|
\
|
||||||
/* Now we have saved LR we can use it instead of R0. */ \
|
/* Now we have saved LR we can use it instead of R0. */ \
|
||||||
"MOV LR, R0 \n\t" \
|
"MOV LR, R0 \n\t" \
|
||||||
\
|
\
|
||||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||||
"LDMIA SP!, {R0} \n\t" \
|
"LDMIA SP!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Push all the system mode registers onto the task stack. */ \
|
/* Push all the system mode registers onto the task stack. */ \
|
||||||
"STMDB LR,{R0-LR}^ \n\t" \
|
"STMDB LR,{R0-LR}^ \n\t" \
|
||||||
"NOP \n\t" \
|
"NOP \n\t" \
|
||||||
"SUB LR, LR, #60 \n\t" \
|
"SUB LR, LR, #60 \n\t" \
|
||||||
\
|
\
|
||||||
/* Push the SPSR onto the task stack. */ \
|
/* Push the SPSR onto the task stack. */ \
|
||||||
"MRS R0, SPSR \n\t" \
|
"MRS R0, SPSR \n\t" \
|
||||||
"STMDB LR!, {R0} \n\t" \
|
"STMDB LR!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
"LDR R0, =ulCriticalNesting \n\t" \
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t" \
|
||||||
"STMDB LR!, {R0} \n\t" \
|
"STMDB LR!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Store the new top of stack for the task. */ \
|
/* Store the new top of stack for the task. */ \
|
||||||
"LDR R0, =pxCurrentTCB \n\t" \
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t" \
|
||||||
"STR LR, [R0] \n\t" \
|
"STR LR, [R0] \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void vTaskSwitchContext( void );
|
extern void vTaskSwitchContext( void );
|
||||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -186,42 +186,42 @@ extern void vTaskSwitchContext( void );
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -28,12 +28,12 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||||
*
|
*
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in this file. The ISR routines, which can only be compiled
|
* contained in this file. The ISR routines, which can only be compiled
|
||||||
* to ARM mode are contained in portISR.c.
|
* to ARM mode are contained in portISR.c.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
|
@ -44,21 +44,21 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/* Constants required to setup the task context. */
|
/* Constants required to setup the task context. */
|
||||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
||||||
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
||||||
|
|
||||||
/* Constants required to setup the tick ISR. */
|
/* Constants required to setup the tick ISR. */
|
||||||
#define portENABLE_TIMER ( ( uint8_t ) 0x01 )
|
#define portENABLE_TIMER ( ( uint8_t ) 0x01 )
|
||||||
#define portPRESCALE_VALUE 0x00
|
#define portPRESCALE_VALUE 0x00
|
||||||
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
|
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
|
||||||
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
|
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
|
||||||
|
|
||||||
/* Constants required to setup the VIC for the tick ISR. */
|
/* Constants required to setup the VIC for the tick ISR. */
|
||||||
#define portTIMER_VIC_CHANNEL ( ( uint32_t ) 0x0004 )
|
#define portTIMER_VIC_CHANNEL ( ( uint32_t ) 0x0004 )
|
||||||
#define portTIMER_VIC_CHANNEL_BIT ( ( uint32_t ) 0x0010 )
|
#define portTIMER_VIC_CHANNEL_BIT ( ( uint32_t ) 0x0010 )
|
||||||
#define portTIMER_VIC_ENABLE ( ( uint32_t ) 0x0020 )
|
#define portTIMER_VIC_ENABLE ( ( uint32_t ) 0x0020 )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -79,61 +79,63 @@ extern void vPortISRStartFirstTask( void );
|
||||||
*
|
*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
StackType_t *pxOriginalTOS;
|
StackType_t * pxOriginalTOS;
|
||||||
|
|
||||||
pxOriginalTOS = pxTopOfStack;
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
is not really required. */
|
* is not really required. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro. */
|
* expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First on the stack is the return address - which in this case is the
|
/* First on the stack is the return address - which in this case is the
|
||||||
start of the task. The offset is added to make the return address appear
|
* start of the task. The offset is added to make the return address appear
|
||||||
as it would within an IRQ ISR. */
|
* as it would within an IRQ ISR. */
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */
|
*pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* When the task starts is will expect to find the function parameter in
|
/* When the task starts is will expect to find the function parameter in
|
||||||
R0. */
|
* R0. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The last thing onto the stack is the status register, which is set for
|
/* The last thing onto the stack is the status register, which is set for
|
||||||
system mode, with interrupts enabled. */
|
* system mode, with interrupts enabled. */
|
||||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||||
|
|
||||||
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
||||||
|
@ -145,9 +147,9 @@ StackType_t *pxOriginalTOS;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Some optimisation levels use the stack differently to others. This
|
/* Some optimisation levels use the stack differently to others. This
|
||||||
means the interrupt flags cannot always be stored on the stack and will
|
* means the interrupt flags cannot always be stored on the stack and will
|
||||||
instead be stored in a variable, which is then saved as part of the
|
* instead be stored in a variable, which is then saved as part of the
|
||||||
tasks context. */
|
* tasks context. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -157,7 +159,7 @@ StackType_t *pxOriginalTOS;
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
here already. */
|
* here already. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
|
@ -171,7 +173,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the ARM port will require this function as there
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
is nothing to return to. */
|
* is nothing to return to. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -180,21 +182,21 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
uint32_t ulCompareMatch;
|
uint32_t ulCompareMatch;
|
||||||
|
|
||||||
PCLKSEL0 = (PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);
|
PCLKSEL0 = ( PCLKSEL0 & ( ~( 0x3 << 2 ) ) ) | ( 0x01 << 2 );
|
||||||
T0TCR = 2; /* Stop and reset the timer */
|
T0TCR = 2; /* Stop and reset the timer */
|
||||||
T0CTCR = 0; /* Timer mode */
|
T0CTCR = 0; /* Timer mode */
|
||||||
|
|
||||||
/* A 1ms tick does not require the use of the timer prescale. This is
|
/* A 1ms tick does not require the use of the timer prescale. This is
|
||||||
defaulted to zero but can be used if necessary. */
|
* defaulted to zero but can be used if necessary. */
|
||||||
T0PR = portPRESCALE_VALUE;
|
T0PR = portPRESCALE_VALUE;
|
||||||
|
|
||||||
/* Calculate the match value required for our wanted tick rate. */
|
/* Calculate the match value required for our wanted tick rate. */
|
||||||
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||||
|
|
||||||
/* Protect against divide by zero. Using an if() statement still results
|
/* Protect against divide by zero. Using an if() statement still results
|
||||||
in a warning - hence the #if. */
|
* in a warning - hence the #if. */
|
||||||
#if portPRESCALE_VALUE != 0
|
#if portPRESCALE_VALUE != 0
|
||||||
{
|
{
|
||||||
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
||||||
|
@ -203,21 +205,21 @@ uint32_t ulCompareMatch;
|
||||||
T0MR1 = ulCompareMatch;
|
T0MR1 = ulCompareMatch;
|
||||||
|
|
||||||
/* Generate tick with timer 0 compare match. */
|
/* Generate tick with timer 0 compare match. */
|
||||||
T0MCR = (3 << 3); /* Reset timer on match and generate interrupt */
|
T0MCR = ( 3 << 3 ); /* Reset timer on match and generate interrupt */
|
||||||
|
|
||||||
/* Setup the VIC for the timer. */
|
/* Setup the VIC for the timer. */
|
||||||
VICIntEnable = 0x00000010;
|
VICIntEnable = 0x00000010;
|
||||||
|
|
||||||
/* The ISR installed depends on whether the preemptive or cooperative
|
/* The ISR installed depends on whether the preemptive or cooperative
|
||||||
scheduler is being used. */
|
* scheduler is being used. */
|
||||||
#if configUSE_PREEMPTION == 1
|
#if configUSE_PREEMPTION == 1
|
||||||
{
|
{
|
||||||
extern void ( vPreemptiveTick )( void );
|
extern void( vPreemptiveTick )( void );
|
||||||
VICVectAddr4 = ( int32_t ) vPreemptiveTick;
|
VICVectAddr4 = ( int32_t ) vPreemptiveTick;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
extern void ( vNonPreemptiveTick )( void );
|
extern void( vNonPreemptiveTick )( void );
|
||||||
VICVectAddr4 = ( int32_t ) vNonPreemptiveTick;
|
VICVectAddr4 = ( int32_t ) vNonPreemptiveTick;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -225,7 +227,7 @@ uint32_t ulCompareMatch;
|
||||||
VICVectCntl4 = 1;
|
VICVectCntl4 = 1;
|
||||||
|
|
||||||
/* Start the timer - interrupts are disabled when this function is called
|
/* Start the timer - interrupts are disabled when this function is called
|
||||||
so it is okay to do this here. */
|
* so it is okay to do this here. */
|
||||||
T0TCR = portENABLE_TIMER;
|
T0TCR = portENABLE_TIMER;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
@ -28,27 +28,27 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in port.c The ISR routines, which can only be compiled
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
* to ARM mode, are contained in this file.
|
* to ARM mode, are contained in this file.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/* Constants required to handle interrupts. */
|
/* Constants required to handle interrupts. */
|
||||||
#define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 )
|
#define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 )
|
||||||
#define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 )
|
#define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 )
|
||||||
|
|
||||||
/* Constants required to handle critical sections. */
|
/* Constants required to handle critical sections. */
|
||||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||||
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
void vPortYieldProcessor( void ) __attribute__( ( interrupt( "SWI" ), naked ) );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
@ -60,7 +60,7 @@ void vPortISRStartFirstTask( void );
|
||||||
void vPortISRStartFirstTask( void )
|
void vPortISRStartFirstTask( void )
|
||||||
{
|
{
|
||||||
/* Simply start the scheduler. This is included here as it can only be
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
called from ARM mode. */
|
* called from ARM mode. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -76,15 +76,15 @@ void vPortISRStartFirstTask( void )
|
||||||
void vPortYieldProcessor( void )
|
void vPortYieldProcessor( void )
|
||||||
{
|
{
|
||||||
/* Within an IRQ ISR the link register has an offset from the true return
|
/* Within an IRQ ISR the link register has an offset from the true return
|
||||||
address, but an SWI ISR does not. Add the offset manually so the same
|
* address, but an SWI ISR does not. Add the offset manually so the same
|
||||||
ISR return code can be used in both cases. */
|
* ISR return code can be used in both cases. */
|
||||||
__asm volatile ( "ADD LR, LR, #4" );
|
__asm volatile ( "ADD LR, LR, #4" );
|
||||||
|
|
||||||
/* Perform the context switch. First save the context of the current task. */
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
/* Find the highest priority task that is ready to run. */
|
/* Find the highest priority task that is ready to run. */
|
||||||
__asm volatile( "bl vTaskSwitchContext" );
|
__asm volatile ( "bl vTaskSwitchContext" );
|
||||||
|
|
||||||
/* Restore the context of the new task. */
|
/* Restore the context of the new task. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
|
@ -99,9 +99,9 @@ void vPortYieldProcessor( void )
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
simply increment the system tick. */
|
* simply increment the system tick. */
|
||||||
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
|
||||||
void vNonPreemptiveTick( void )
|
void vNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
|
@ -109,18 +109,18 @@ void vPortYieldProcessor( void )
|
||||||
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else /* if configUSE_PREEMPTION == 0 */
|
||||||
|
|
||||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||||
saved on entry as part of the context switch. */
|
* saved on entry as part of the context switch. */
|
||||||
void vPreemptiveTick( void ) __attribute__((naked));
|
void vPreemptiveTick( void ) __attribute__( ( naked ) );
|
||||||
void vPreemptiveTick( void )
|
void vPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the interrupted task. */
|
/* Save the context of the interrupted task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
/* Increment the RTOS tick count, then look for the highest priority
|
/* Increment the RTOS tick count, then look for the highest priority
|
||||||
task that is ready to run. */
|
* task that is ready to run. */
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" bl xTaskIncrementTick \t\n" \
|
" bl xTaskIncrementTick \t\n" \
|
||||||
|
@ -138,7 +138,7 @@ void vPortYieldProcessor( void )
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* if configUSE_PREEMPTION == 0 */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -149,50 +149,50 @@ void vPortYieldProcessor( void )
|
||||||
*/
|
*/
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void )
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
"BX R14" ); /* Return back to thumb. */
|
"BX R14" ); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void vPortEnableInterruptsFromThumb( void )
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
"BX R14" ); /* Return back to thumb. */
|
"BX R14" ); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
different optimisation levels. The interrupt flags can therefore not always
|
* different optimisation levels. The interrupt flags can therefore not always
|
||||||
be saved to the stack. Instead the critical section nesting level is stored
|
* be saved to the stack. Instead the critical section nesting level is stored
|
||||||
in a variable, which is then saved as part of the stack context. */
|
* in a variable, which is then saved as part of the stack context. */
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now that interrupts are disabled, ulCriticalNesting can be accessed
|
||||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
portENTER_CRITICAL() has been called. */
|
* portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,16 +204,16 @@ void vPortExitCritical( void )
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then interrupts should be
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
re-enabled. */
|
* re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,27 +27,27 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V3.2.3
|
* Changes from V3.2.3
|
||||||
|
*
|
||||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||||
|
+
|
||||||
Changes from V3.2.4
|
+ Changes from V3.2.4
|
||||||
|
+
|
||||||
+ Removed the use of the %0 parameter within the assembler macros and
|
+ Removed the use of the %0 parameter within the assembler macros and
|
||||||
replaced them with hard coded registers. This will ensure the
|
+ replaced them with hard coded registers. This will ensure the
|
||||||
assembler does not select the link register as the temp register as
|
+ assembler does not select the link register as the temp register as
|
||||||
was occasionally happening previously.
|
+ was occasionally happening previously.
|
||||||
|
+
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
than each line having its own asm block.
|
+ than each line having its own asm block.
|
||||||
|
+
|
||||||
Changes from V4.5.0
|
+ Changes from V4.5.0
|
||||||
|
+
|
||||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||||
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
+ and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||||
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
+ should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||||
macros as per the V4.5.1 demo code.
|
+ macros as per the V4.5.1 demo code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
@ -69,34 +69,34 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE portLONG
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
#define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL )
|
||||||
#else
|
#else
|
||||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP() __asm volatile ( "NOP" );
|
#define portNOP() __asm volatile ( "NOP" );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,92 +109,92 @@ typedef unsigned long UBaseType_t;
|
||||||
* THUMB mode code will result in a compile time error.
|
* THUMB mode code will result in a compile time error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Set the LR to the task stack. */ \
|
/* Set the LR to the task stack. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"LDR R0, =pxCurrentTCB \n\t" \
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t" \
|
||||||
"LDR LR, [R0] \n\t" \
|
"LDR LR, [R0] \n\t" \
|
||||||
\
|
\
|
||||||
/* The critical nesting depth is the first item on the stack. */ \
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
/* Load it into the ulCriticalNesting variable. */ \
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
"LDR R0, =ulCriticalNesting \n\t" \
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
"LDMFD LR!, {R1} \n\t" \
|
"LDMFD LR!, {R1} \n\t" \
|
||||||
"STR R1, [R0] \n\t" \
|
"STR R1, [R0] \n\t" \
|
||||||
\
|
\
|
||||||
/* Get the SPSR from the stack. */ \
|
/* Get the SPSR from the stack. */ \
|
||||||
"LDMFD LR!, {R0} \n\t" \
|
"LDMFD LR!, {R0} \n\t" \
|
||||||
"MSR SPSR, R0 \n\t" \
|
"MSR SPSR, R0 \n\t" \
|
||||||
\
|
\
|
||||||
/* Restore all system mode registers for the task. */ \
|
/* Restore all system mode registers for the task. */ \
|
||||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||||
"NOP \n\t" \
|
"NOP \n\t" \
|
||||||
\
|
\
|
||||||
/* Restore the return address. */ \
|
/* Restore the return address. */ \
|
||||||
"LDR LR, [LR, #+60] \n\t" \
|
"LDR LR, [LR, #+60] \n\t" \
|
||||||
\
|
\
|
||||||
/* And return - correcting the offset in the LR to obtain the */ \
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
/* correct address. */ \
|
/* correct address. */ \
|
||||||
"SUBS PC, LR, #4 \n\t" \
|
"SUBS PC, LR, #4 \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Push R0 as we are going to use the register. */ \
|
/* Push R0 as we are going to use the register. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" \
|
"STMDB SP!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Set R0 to point to the task stack pointer. */ \
|
/* Set R0 to point to the task stack pointer. */ \
|
||||||
"STMDB SP,{SP}^ \n\t" \
|
"STMDB SP,{SP}^ \n\t" \
|
||||||
"NOP \n\t" \
|
"NOP \n\t" \
|
||||||
"SUB SP, SP, #4 \n\t" \
|
"SUB SP, SP, #4 \n\t" \
|
||||||
"LDMIA SP!,{R0} \n\t" \
|
"LDMIA SP!,{R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Push the return address onto the stack. */ \
|
/* Push the return address onto the stack. */ \
|
||||||
"STMDB R0!, {LR} \n\t" \
|
"STMDB R0!, {LR} \n\t" \
|
||||||
\
|
\
|
||||||
/* Now we have saved LR we can use it instead of R0. */ \
|
/* Now we have saved LR we can use it instead of R0. */ \
|
||||||
"MOV LR, R0 \n\t" \
|
"MOV LR, R0 \n\t" \
|
||||||
\
|
\
|
||||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||||
"LDMIA SP!, {R0} \n\t" \
|
"LDMIA SP!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Push all the system mode registers onto the task stack. */ \
|
/* Push all the system mode registers onto the task stack. */ \
|
||||||
"STMDB LR,{R0-LR}^ \n\t" \
|
"STMDB LR,{R0-LR}^ \n\t" \
|
||||||
"NOP \n\t" \
|
"NOP \n\t" \
|
||||||
"SUB LR, LR, #60 \n\t" \
|
"SUB LR, LR, #60 \n\t" \
|
||||||
\
|
\
|
||||||
/* Push the SPSR onto the task stack. */ \
|
/* Push the SPSR onto the task stack. */ \
|
||||||
"MRS R0, SPSR \n\t" \
|
"MRS R0, SPSR \n\t" \
|
||||||
"STMDB LR!, {R0} \n\t" \
|
"STMDB LR!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
"LDR R0, =ulCriticalNesting \n\t" \
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t" \
|
||||||
"STMDB LR!, {R0} \n\t" \
|
"STMDB LR!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Store the new top of stack for the task. */ \
|
/* Store the new top of stack for the task. */ \
|
||||||
"LDR R0, =pxCurrentTCB \n\t" \
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t" \
|
||||||
"STR LR, [R0] \n\t" \
|
"STR LR, [R0] \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -209,42 +209,42 @@ extern volatile uint32_t ulCriticalNesting; \
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -34,104 +34,104 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
|
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
|
||||||
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error "configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
|
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
|
||||||
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error "configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
||||||
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error "configUNIQUE_INTERRUPT_PRIORITIES must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configSETUP_TICK_INTERRUPT
|
#ifndef configSETUP_TICK_INTERRUPT
|
||||||
#error configSETUP_TICK_INTERRUPT() must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error "configSETUP_TICK_INTERRUPT() must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||||
#endif /* configSETUP_TICK_INTERRUPT */
|
#endif /* configSETUP_TICK_INTERRUPT */
|
||||||
|
|
||||||
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0
|
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY > configUNIQUE_INTERRUPT_PRIORITIES
|
#if configMAX_API_CALL_INTERRUPT_PRIORITY > configUNIQUE_INTERRUPT_PRIORITIES
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority
|
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if( configMAX_PRIORITIES > 32 )
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error "configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice."
|
||||||
#endif
|
#endif
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
/* In case security extensions are implemented. */
|
/* In case security extensions are implemented. */
|
||||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
|
#if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
|
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
||||||
portmacro.h. */
|
* portmacro.h. */
|
||||||
#ifndef configCLEAR_TICK_INTERRUPT
|
#ifndef configCLEAR_TICK_INTERRUPT
|
||||||
#define configCLEAR_TICK_INTERRUPT()
|
#define configCLEAR_TICK_INTERRUPT()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* A critical section is exited when the critical section nesting count reaches
|
/* A critical section is exited when the critical section nesting count reaches
|
||||||
this value. */
|
* this value. */
|
||||||
#define portNO_CRITICAL_NESTING ( ( size_t ) 0 )
|
#define portNO_CRITICAL_NESTING ( ( size_t ) 0 )
|
||||||
|
|
||||||
/* In all GICs 255 can be written to the priority mask register to unmask all
|
/* In all GICs 255 can be written to the priority mask register to unmask all
|
||||||
(but the lowest) interrupt priority. */
|
* (but the lowest) interrupt priority. */
|
||||||
#define portUNMASK_VALUE ( 0xFFUL )
|
#define portUNMASK_VALUE ( 0xFFUL )
|
||||||
|
|
||||||
/* Tasks are not created with a floating point context, but can be given a
|
/* Tasks are not created with a floating point context, but can be given a
|
||||||
floating point context after they have been created. A variable is stored as
|
* floating point context after they have been created. A variable is stored as
|
||||||
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
* part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||||
does not have an FPU context, or any other value if the task does have an FPU
|
* does not have an FPU context, or any other value if the task does have an FPU
|
||||||
context. */
|
* context. */
|
||||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||||
|
|
||||||
/* Constants required to setup the initial task context. */
|
/* Constants required to setup the initial task context. */
|
||||||
#define portSP_ELx ( ( StackType_t ) 0x01 )
|
#define portSP_ELx ( ( StackType_t ) 0x01 )
|
||||||
#define portSP_EL0 ( ( StackType_t ) 0x00 )
|
#define portSP_EL0 ( ( StackType_t ) 0x00 )
|
||||||
|
|
||||||
#if defined( GUEST )
|
#if defined( GUEST )
|
||||||
#define portEL1 ( ( StackType_t ) 0x04 )
|
#define portEL1 ( ( StackType_t ) 0x04 )
|
||||||
#define portINITIAL_PSTATE ( portEL1 | portSP_EL0 )
|
#define portINITIAL_PSTATE ( portEL1 | portSP_EL0 )
|
||||||
#else
|
#else
|
||||||
#define portEL3 ( ( StackType_t ) 0x0c )
|
#define portEL3 ( ( StackType_t ) 0x0c )
|
||||||
/* At the time of writing, the BSP only supports EL3. */
|
/* At the time of writing, the BSP only supports EL3. */
|
||||||
#define portINITIAL_PSTATE ( portEL3 | portSP_EL0 )
|
#define portINITIAL_PSTATE ( portEL3 | portSP_EL0 )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
||||||
point is zero. */
|
* point is zero. */
|
||||||
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
||||||
|
|
||||||
/* Masks all bits in the APSR other than the mode bits. */
|
/* Masks all bits in the APSR other than the mode bits. */
|
||||||
#define portAPSR_MODE_BITS_MASK ( 0x0C )
|
#define portAPSR_MODE_BITS_MASK ( 0x0C )
|
||||||
|
|
||||||
/* The I bit in the DAIF bits. */
|
/* The I bit in the DAIF bits. */
|
||||||
#define portDAIF_I ( 0x80 )
|
#define portDAIF_I ( 0x80 )
|
||||||
|
|
||||||
/* Macro to unmask all interrupt priorities. */
|
/* Macro to unmask all interrupt priorities. */
|
||||||
#define portCLEAR_INTERRUPT_MASK() \
|
#define portCLEAR_INTERRUPT_MASK() \
|
||||||
{ \
|
{ \
|
||||||
portDISABLE_INTERRUPTS(); \
|
portDISABLE_INTERRUPTS(); \
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
||||||
__asm volatile ( "DSB SY \n" \
|
__asm volatile ( "DSB SY \n" \
|
||||||
"ISB SY \n" ); \
|
"ISB SY \n" ); \
|
||||||
portENABLE_INTERRUPTS(); \
|
portENABLE_INTERRUPTS(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hardware specifics used when sanity checking the configuration. */
|
/* Hardware specifics used when sanity checking the configuration. */
|
||||||
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
|
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
|
||||||
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
||||||
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
|
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -144,104 +144,106 @@ extern void vPortRestoreTaskContext( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* A variable is used to keep track of the critical section nesting. This
|
/* A variable is used to keep track of the critical section nesting. This
|
||||||
variable has to be stored as part of the task context and must be initialised to
|
* variable has to be stored as part of the task context and must be initialised to
|
||||||
a non zero value to ensure interrupts don't inadvertently become unmasked before
|
* a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||||
the scheduler starts. As it is stored as part of the task context it will
|
* the scheduler starts. As it is stored as part of the task context it will
|
||||||
automatically be set to 0 when the first task is started. */
|
* automatically be set to 0 when the first task is started. */
|
||||||
volatile uint64_t ullCriticalNesting = 9999ULL;
|
volatile uint64_t ullCriticalNesting = 9999ULL;
|
||||||
|
|
||||||
/* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero
|
/* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero
|
||||||
then floating point context must be saved and restored for the task. */
|
* then floating point context must be saved and restored for the task. */
|
||||||
uint64_t ullPortTaskHasFPUContext = pdFALSE;
|
uint64_t ullPortTaskHasFPUContext = pdFALSE;
|
||||||
|
|
||||||
/* Set to 1 to pend a context switch from an ISR. */
|
/* Set to 1 to pend a context switch from an ISR. */
|
||||||
uint64_t ullPortYieldRequired = pdFALSE;
|
uint64_t ullPortYieldRequired = pdFALSE;
|
||||||
|
|
||||||
/* Counts the interrupt nesting depth. A context switch is only performed if
|
/* Counts the interrupt nesting depth. A context switch is only performed if
|
||||||
if the nesting depth is 0. */
|
* if the nesting depth is 0. */
|
||||||
uint64_t ullPortInterruptNesting = 0;
|
uint64_t ullPortInterruptNesting = 0;
|
||||||
|
|
||||||
/* Used in the ASM code. */
|
/* Used in the ASM code. */
|
||||||
__attribute__(( used )) const uint64_t ullICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;
|
__attribute__( ( used ) ) const uint64_t ullICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;
|
||||||
__attribute__(( used )) const uint64_t ullICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;
|
__attribute__( ( used ) ) const uint64_t ullICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;
|
||||||
__attribute__(( used )) const uint64_t ullICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;
|
__attribute__( ( used ) ) const uint64_t ullICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;
|
||||||
__attribute__(( used )) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
__attribute__( ( used ) ) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro. */
|
* expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First all the general purpose registers. */
|
/* First all the general purpose registers. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0101010101010101ULL; /* R1 */
|
*pxTopOfStack = 0x0101010101010101ULL; /* R1 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0303030303030303ULL; /* R3 */
|
*pxTopOfStack = 0x0303030303030303ULL; /* R3 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0202020202020202ULL; /* R2 */
|
*pxTopOfStack = 0x0202020202020202ULL; /* R2 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0505050505050505ULL; /* R5 */
|
*pxTopOfStack = 0x0505050505050505ULL; /* R5 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0404040404040404ULL; /* R4 */
|
*pxTopOfStack = 0x0404040404040404ULL; /* R4 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0707070707070707ULL; /* R7 */
|
*pxTopOfStack = 0x0707070707070707ULL; /* R7 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0606060606060606ULL; /* R6 */
|
*pxTopOfStack = 0x0606060606060606ULL; /* R6 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0909090909090909ULL; /* R9 */
|
*pxTopOfStack = 0x0909090909090909ULL; /* R9 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0808080808080808ULL; /* R8 */
|
*pxTopOfStack = 0x0808080808080808ULL; /* R8 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1111111111111111ULL; /* R11 */
|
*pxTopOfStack = 0x1111111111111111ULL; /* R11 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1010101010101010ULL; /* R10 */
|
*pxTopOfStack = 0x1010101010101010ULL; /* R10 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1313131313131313ULL; /* R13 */
|
*pxTopOfStack = 0x1313131313131313ULL; /* R13 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1212121212121212ULL; /* R12 */
|
*pxTopOfStack = 0x1212121212121212ULL; /* R12 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1515151515151515ULL; /* R15 */
|
*pxTopOfStack = 0x1515151515151515ULL; /* R15 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1414141414141414ULL; /* R14 */
|
*pxTopOfStack = 0x1414141414141414ULL; /* R14 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1717171717171717ULL; /* R17 */
|
*pxTopOfStack = 0x1717171717171717ULL; /* R17 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1616161616161616ULL; /* R16 */
|
*pxTopOfStack = 0x1616161616161616ULL; /* R16 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1919191919191919ULL; /* R19 */
|
*pxTopOfStack = 0x1919191919191919ULL; /* R19 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1818181818181818ULL; /* R18 */
|
*pxTopOfStack = 0x1818181818181818ULL; /* R18 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2121212121212121ULL; /* R21 */
|
*pxTopOfStack = 0x2121212121212121ULL; /* R21 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2020202020202020ULL; /* R20 */
|
*pxTopOfStack = 0x2020202020202020ULL; /* R20 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2323232323232323ULL; /* R23 */
|
*pxTopOfStack = 0x2323232323232323ULL; /* R23 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2222222222222222ULL; /* R22 */
|
*pxTopOfStack = 0x2222222222222222ULL; /* R22 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2525252525252525ULL; /* R25 */
|
*pxTopOfStack = 0x2525252525252525ULL; /* R25 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2424242424242424ULL; /* R24 */
|
*pxTopOfStack = 0x2424242424242424ULL; /* R24 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2727272727272727ULL; /* R27 */
|
*pxTopOfStack = 0x2727272727272727ULL; /* R27 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2626262626262626ULL; /* R26 */
|
*pxTopOfStack = 0x2626262626262626ULL; /* R26 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2929292929292929ULL; /* R29 */
|
*pxTopOfStack = 0x2929292929292929ULL; /* R29 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2828282828282828ULL; /* R28 */
|
*pxTopOfStack = 0x2828282828282828ULL; /* R28 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */
|
*pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */
|
*pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
*pxTopOfStack = portINITIAL_PSTATE;
|
*pxTopOfStack = portINITIAL_PSTATE;
|
||||||
|
@ -251,13 +253,13 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||||
enabled. */
|
* enabled. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The task will start without a floating point context. A task that uses
|
/* The task will start without a floating point context. A task that uses
|
||||||
the floating point hardware must call vPortTaskUsesFPU() before executing
|
* the floating point hardware must call vPortTaskUsesFPU() before executing
|
||||||
any floating point instructions. */
|
* any floating point instructions. */
|
||||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -266,21 +268,21 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulAPSR;
|
uint32_t ulAPSR;
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint8_t ucOriginalPriority;
|
volatile uint8_t ucOriginalPriority;
|
||||||
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );
|
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine how many priority bits are implemented in the GIC.
|
/* Determine how many priority bits are implemented in the GIC.
|
||||||
|
*
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
* Save the interrupt priority value that is about to be clobbered. */
|
||||||
ucOriginalPriority = *pucFirstUserPriorityRegister;
|
ucOriginalPriority = *pucFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to
|
/* Determine the number of priority bits available. First write to
|
||||||
all possible bits. */
|
* all possible bits. */
|
||||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -293,13 +295,13 @@ uint32_t ulAPSR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
||||||
value. */
|
* value. */
|
||||||
|
|
||||||
configASSERT( ucMaxPriorityValue >= portLOWEST_INTERRUPT_PRIORITY );
|
configASSERT( ucMaxPriorityValue >= portLOWEST_INTERRUPT_PRIORITY );
|
||||||
|
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
value. */
|
* value. */
|
||||||
*pucFirstUserPriorityRegister = ucOriginalPriority;
|
*pucFirstUserPriorityRegister = ucOriginalPriority;
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
@ -309,26 +311,28 @@ uint32_t ulAPSR;
|
||||||
__asm volatile ( "MRS %0, CurrentEL" : "=r" ( ulAPSR ) );
|
__asm volatile ( "MRS %0, CurrentEL" : "=r" ( ulAPSR ) );
|
||||||
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
||||||
|
|
||||||
#if defined( GUEST )
|
#if defined( GUEST )
|
||||||
#warning Building for execution as a guest under XEN. THIS IS NOT A FULLY TESTED PATH.
|
#warning "Building for execution as a guest under XEN. THIS IS NOT A FULLY TESTED PATH."
|
||||||
configASSERT( ulAPSR == portEL1 );
|
configASSERT( ulAPSR == portEL1 );
|
||||||
if( ulAPSR == portEL1 )
|
|
||||||
#else
|
if( ulAPSR == portEL1 )
|
||||||
configASSERT( ulAPSR == portEL3 );
|
#else
|
||||||
if( ulAPSR == portEL3 )
|
configASSERT( ulAPSR == portEL3 );
|
||||||
#endif
|
|
||||||
|
if( ulAPSR == portEL3 )
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/* Only continue if the binary point value is set to its lowest possible
|
/* Only continue if the binary point value is set to its lowest possible
|
||||||
setting. See the comments in vPortValidateInterruptPriority() below for
|
* setting. See the comments in vPortValidateInterruptPriority() below for
|
||||||
more information. */
|
* more information. */
|
||||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||||
|
|
||||||
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
||||||
{
|
{
|
||||||
/* Interrupts are turned off in the CPU itself to ensure a tick does
|
/* Interrupts are turned off in the CPU itself to ensure a tick does
|
||||||
not execute while the scheduler is being started. Interrupts are
|
* not execute while the scheduler is being started. Interrupts are
|
||||||
automatically turned back on in the CPU when the first task starts
|
* automatically turned back on in the CPU when the first task starts
|
||||||
executing. */
|
* executing. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. */
|
/* Start the timer that generates the tick ISR. */
|
||||||
|
@ -346,7 +350,7 @@ uint32_t ulAPSR;
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Not implemented in ports where there is nothing to return to.
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
Artificially force an assert. */
|
* Artificially force an assert. */
|
||||||
configASSERT( ullCriticalNesting == 1000ULL );
|
configASSERT( ullCriticalNesting == 1000ULL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -357,15 +361,15 @@ void vPortEnterCritical( void )
|
||||||
uxPortSetInterruptMask();
|
uxPortSetInterruptMask();
|
||||||
|
|
||||||
/* Now interrupts are disabled ullCriticalNesting can be accessed
|
/* Now interrupts are disabled ullCriticalNesting can be accessed
|
||||||
directly. Increment ullCriticalNesting to keep a count of how many times
|
* directly. Increment ullCriticalNesting to keep a count of how many times
|
||||||
portENTER_CRITICAL() has been called. */
|
* portENTER_CRITICAL() has been called. */
|
||||||
ullCriticalNesting++;
|
ullCriticalNesting++;
|
||||||
|
|
||||||
/* This is not the interrupt safe version of the enter critical function so
|
/* This is not the interrupt safe version of the enter critical function so
|
||||||
assert() if it is being called from an interrupt context. Only API
|
* assert() if it is being called from an interrupt context. Only API
|
||||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||||
the critical nesting count is 1 to protect against recursive calls if the
|
* the critical nesting count is 1 to protect against recursive calls if the
|
||||||
assert function also uses a critical section. */
|
* assert function also uses a critical section. */
|
||||||
if( ullCriticalNesting == 1ULL )
|
if( ullCriticalNesting == 1ULL )
|
||||||
{
|
{
|
||||||
configASSERT( ullPortInterruptNesting == 0 );
|
configASSERT( ullPortInterruptNesting == 0 );
|
||||||
|
@ -378,15 +382,15 @@ void vPortExitCritical( void )
|
||||||
if( ullCriticalNesting > portNO_CRITICAL_NESTING )
|
if( ullCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Decrement the nesting count as the critical section is being
|
/* Decrement the nesting count as the critical section is being
|
||||||
exited. */
|
* exited. */
|
||||||
ullCriticalNesting--;
|
ullCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then all interrupt
|
/* If the nesting level has reached zero then all interrupt
|
||||||
priorities must be re-enabled. */
|
* priorities must be re-enabled. */
|
||||||
if( ullCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ullCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Critical nesting has reached zero so all interrupt priorities
|
/* Critical nesting has reached zero so all interrupt priorities
|
||||||
should be unmasked. */
|
* should be unmasked. */
|
||||||
portCLEAR_INTERRUPT_MASK();
|
portCLEAR_INTERRUPT_MASK();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -403,23 +407,23 @@ void FreeRTOS_Tick_Handler( void )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Interrupts should not be enabled before this point. */
|
/* Interrupts should not be enabled before this point. */
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
uint32_t ulMaskBits;
|
uint32_t ulMaskBits;
|
||||||
|
|
||||||
__asm volatile( "mrs %0, daif" : "=r"( ulMaskBits ) :: "memory" );
|
__asm volatile ( "mrs %0, daif" : "=r" ( ulMaskBits )::"memory" );
|
||||||
configASSERT( ( ulMaskBits & portDAIF_I ) != 0 );
|
configASSERT( ( ulMaskBits & portDAIF_I ) != 0 );
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
/* Set interrupt mask before altering scheduler structures. The tick
|
/* Set interrupt mask before altering scheduler structures. The tick
|
||||||
handler runs at the lowest priority, so interrupts cannot already be masked,
|
* handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||||
so there is no need to save and restore the current mask value. It is
|
* so there is no need to save and restore the current mask value. It is
|
||||||
necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
* necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||||
updated. */
|
* updated. */
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
__asm volatile ( "dsb sy \n"
|
__asm volatile ( "dsb sy \n"
|
||||||
"isb sy \n" ::: "memory" );
|
"isb sy \n" ::: "memory" );
|
||||||
|
|
||||||
/* Ok to enable interrupts after the interrupt source has been cleared. */
|
/* Ok to enable interrupts after the interrupt source has been cleared. */
|
||||||
configCLEAR_TICK_INTERRUPT();
|
configCLEAR_TICK_INTERRUPT();
|
||||||
|
@ -439,11 +443,11 @@ void FreeRTOS_Tick_Handler( void )
|
||||||
void vPortTaskUsesFPU( void )
|
void vPortTaskUsesFPU( void )
|
||||||
{
|
{
|
||||||
/* A task is registering the fact that it needs an FPU context. Set the
|
/* A task is registering the fact that it needs an FPU context. Set the
|
||||||
FPU flag (which is saved as part of the task context). */
|
* FPU flag (which is saved as part of the task context). */
|
||||||
ullPortTaskHasFPUContext = pdTRUE;
|
ullPortTaskHasFPUContext = pdTRUE;
|
||||||
|
|
||||||
/* Consider initialising the FPSR here - but probably not necessary in
|
/* Consider initialising the FPSR here - but probably not necessary in
|
||||||
AArch64. */
|
* AArch64. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -458,11 +462,12 @@ void vPortClearInterruptMask( UBaseType_t uxNewMaskValue )
|
||||||
|
|
||||||
UBaseType_t uxPortSetInterruptMask( void )
|
UBaseType_t uxPortSetInterruptMask( void )
|
||||||
{
|
{
|
||||||
uint32_t ulReturn;
|
uint32_t ulReturn;
|
||||||
|
|
||||||
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
||||||
updated. */
|
* updated. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
||||||
{
|
{
|
||||||
/* Interrupts were already masked. */
|
/* Interrupts were already masked. */
|
||||||
|
@ -472,45 +477,46 @@ uint32_t ulReturn;
|
||||||
{
|
{
|
||||||
ulReturn = pdFALSE;
|
ulReturn = pdFALSE;
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
__asm volatile ( "dsb sy \n"
|
__asm volatile ( "dsb sy \n"
|
||||||
"isb sy \n" ::: "memory" );
|
"isb sy \n" ::: "memory" );
|
||||||
}
|
}
|
||||||
|
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
return ulReturn;
|
return ulReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
|
|
||||||
void vPortValidateInterruptPriority( void )
|
void vPortValidateInterruptPriority( void )
|
||||||
{
|
{
|
||||||
/* The following assertion will fail if a service routine (ISR) for
|
/* The following assertion will fail if a service routine (ISR) for
|
||||||
an interrupt that has been assigned a priority above
|
* an interrupt that has been assigned a priority above
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||||
function. ISR safe FreeRTOS API functions must *only* be called
|
* function. ISR safe FreeRTOS API functions must *only* be called
|
||||||
from interrupts that have been assigned a priority at or below
|
* from interrupts that have been assigned a priority at or below
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
|
*
|
||||||
Numerically low interrupt priority numbers represent logically high
|
* Numerically low interrupt priority numbers represent logically high
|
||||||
interrupt priorities, therefore the priority of the interrupt must
|
* interrupt priorities, therefore the priority of the interrupt must
|
||||||
be set to a value equal to or numerically *higher* than
|
* be set to a value equal to or numerically *higher* than
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
|
*
|
||||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||||
interrupt entry is as fast and simple as possible. */
|
* interrupt entry is as fast and simple as possible. */
|
||||||
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
||||||
|
|
||||||
/* Priority grouping: The interrupt controller (GIC) allows the bits
|
/* Priority grouping: The interrupt controller (GIC) allows the bits
|
||||||
that define each interrupt's priority to be split between bits that
|
* that define each interrupt's priority to be split between bits that
|
||||||
define the interrupt's pre-emption priority bits and bits that define
|
* define the interrupt's pre-emption priority bits and bits that define
|
||||||
the interrupt's sub-priority. For simplicity all bits must be defined
|
* the interrupt's sub-priority. For simplicity all bits must be defined
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
* to be pre-emption priority bits. The following assertion will fail if
|
||||||
this is not the case (if some bits represent a sub-priority).
|
* this is not the case (if some bits represent a sub-priority).
|
||||||
|
*
|
||||||
The priority grouping is configured by the GIC's binary point register
|
* The priority grouping is configured by the GIC's binary point register
|
||||||
(ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
* (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
||||||
possible value (which may be above 0). */
|
* possible value (which may be above 0). */
|
||||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,57 +46,58 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE size_t
|
#define portSTACK_TYPE size_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef portBASE_TYPE BaseType_t;
|
typedef portBASE_TYPE BaseType_t;
|
||||||
typedef uint64_t UBaseType_t;
|
typedef uint64_t UBaseType_t;
|
||||||
|
|
||||||
typedef uint64_t TickType_t;
|
typedef uint64_t TickType_t;
|
||||||
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff )
|
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff )
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 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. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 16
|
#define portBYTE_ALIGNMENT 16
|
||||||
#define portPOINTER_SIZE_TYPE uint64_t
|
#define portPOINTER_SIZE_TYPE uint64_t
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
||||||
/* Called at the end of an ISR that can cause a context switch. */
|
/* Called at the end of an ISR that can cause a context switch. */
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired )\
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
{ \
|
{ \
|
||||||
extern uint64_t ullPortYieldRequired; \
|
extern uint64_t ullPortYieldRequired; \
|
||||||
\
|
\
|
||||||
if( xSwitchRequired != pdFALSE ) \
|
if( xSwitchRequired != pdFALSE ) \
|
||||||
{ \
|
{ \
|
||||||
ullPortYieldRequired = pdTRUE; \
|
ullPortYieldRequired = pdTRUE; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
#if defined( GUEST )
|
#if defined( GUEST )
|
||||||
#define portYIELD() __asm volatile ( "SVC 0" ::: "memory" )
|
#define portYIELD() __asm volatile ( "SVC 0" ::: "memory" )
|
||||||
#else
|
#else
|
||||||
#define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
|
#define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Critical section control
|
* Critical section control
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
@ -104,106 +105,106 @@ extern UBaseType_t uxPortSetInterruptMask( void );
|
||||||
extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue );
|
extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue );
|
||||||
extern void vPortInstallFreeRTOSVectorTable( void );
|
extern void vPortInstallFreeRTOSVectorTable( void );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
__asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \
|
__asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \
|
||||||
__asm volatile ( "DSB SY" ); \
|
__asm volatile ( "DSB SY" ); \
|
||||||
__asm volatile ( "ISB SY" );
|
__asm volatile ( "ISB SY" );
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
__asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \
|
__asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \
|
||||||
__asm volatile ( "DSB SY" ); \
|
__asm volatile ( "DSB SY" ); \
|
||||||
__asm volatile ( "ISB SY" );
|
__asm volatile ( "ISB SY" );
|
||||||
|
|
||||||
|
|
||||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||||
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
not required for this port but included in case common demo code that uses these
|
* not required for this port but included in case common demo code that uses these
|
||||||
macros is used. */
|
* macros is used. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
||||||
handler for whichever peripheral is used to generate the RTOS tick. */
|
* handler for whichever peripheral is used to generate the RTOS tick. */
|
||||||
void FreeRTOS_Tick_Handler( void );
|
void FreeRTOS_Tick_Handler( void );
|
||||||
|
|
||||||
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
||||||
before any floating point instructions are executed. */
|
* before any floating point instructions are executed. */
|
||||||
void vPortTaskUsesFPU( void );
|
void vPortTaskUsesFPU( void );
|
||||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||||
|
|
||||||
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
||||||
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
void vPortValidateInterruptPriority( void );
|
void vPortValidateInterruptPriority( void );
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
#endif /* configASSERT */
|
#endif /* configASSERT */
|
||||||
|
|
||||||
#define portNOP() __asm volatile( "NOP" )
|
#define portNOP() __asm volatile ( "NOP" )
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
|
|
||||||
/* The number of bits to shift for an interrupt priority is dependent on the
|
/* The number of bits to shift for an interrupt priority is dependent on the
|
||||||
number of bits implemented by the interrupt controller. */
|
* number of bits implemented by the interrupt controller. */
|
||||||
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
||||||
#define portPRIORITY_SHIFT 4
|
#define portPRIORITY_SHIFT 4
|
||||||
#define portMAX_BINARY_POINT_VALUE 3
|
#define portMAX_BINARY_POINT_VALUE 3
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
||||||
#define portPRIORITY_SHIFT 3
|
#define portPRIORITY_SHIFT 3
|
||||||
#define portMAX_BINARY_POINT_VALUE 2
|
#define portMAX_BINARY_POINT_VALUE 2
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
||||||
#define portPRIORITY_SHIFT 2
|
#define portPRIORITY_SHIFT 2
|
||||||
#define portMAX_BINARY_POINT_VALUE 1
|
#define portMAX_BINARY_POINT_VALUE 1
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
||||||
#define portPRIORITY_SHIFT 1
|
#define portPRIORITY_SHIFT 1
|
||||||
#define portMAX_BINARY_POINT_VALUE 0
|
#define portMAX_BINARY_POINT_VALUE 0
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
||||||
#define portPRIORITY_SHIFT 0
|
#define portPRIORITY_SHIFT 0
|
||||||
#define portMAX_BINARY_POINT_VALUE 0
|
#define portMAX_BINARY_POINT_VALUE 0
|
||||||
#else
|
#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||||
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
||||||
#endif
|
#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||||
|
|
||||||
/* Interrupt controller access addresses. */
|
/* Interrupt controller access addresses. */
|
||||||
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
||||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
||||||
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
||||||
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
||||||
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
||||||
|
|
||||||
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
||||||
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
||||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
||||||
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
||||||
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
||||||
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
||||||
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
||||||
|
|
||||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -34,92 +34,92 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
||||||
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error "configUNIQUE_INTERRUPT_PRIORITIES must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configSETUP_TICK_INTERRUPT
|
#ifndef configSETUP_TICK_INTERRUPT
|
||||||
#error configSETUP_TICK_INTERRUPT() must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error "configSETUP_TICK_INTERRUPT() must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||||
#endif /* configSETUP_TICK_INTERRUPT */
|
#endif /* configSETUP_TICK_INTERRUPT */
|
||||||
|
|
||||||
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0
|
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY > configUNIQUE_INTERRUPT_PRIORITIES
|
#if configMAX_API_CALL_INTERRUPT_PRIORITY > configUNIQUE_INTERRUPT_PRIORITIES
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority
|
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if( configMAX_PRIORITIES > 32 )
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error "configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice."
|
||||||
#endif
|
#endif
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
/* In case security extensions are implemented. */
|
/* In case security extensions are implemented. */
|
||||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
|
#if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
|
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
||||||
portmacro.h. */
|
* portmacro.h. */
|
||||||
#ifndef configCLEAR_TICK_INTERRUPT
|
#ifndef configCLEAR_TICK_INTERRUPT
|
||||||
#define configCLEAR_TICK_INTERRUPT()
|
#define configCLEAR_TICK_INTERRUPT()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* A critical section is exited when the critical section nesting count reaches
|
/* A critical section is exited when the critical section nesting count reaches
|
||||||
this value. */
|
* this value. */
|
||||||
#define portNO_CRITICAL_NESTING ( ( size_t ) 0 )
|
#define portNO_CRITICAL_NESTING ( ( size_t ) 0 )
|
||||||
|
|
||||||
/* In all GICs 255 can be written to the priority mask register to unmask all
|
/* In all GICs 255 can be written to the priority mask register to unmask all
|
||||||
(but the lowest) interrupt priority. */
|
* (but the lowest) interrupt priority. */
|
||||||
#define portUNMASK_VALUE ( 0xFFUL )
|
#define portUNMASK_VALUE ( 0xFFUL )
|
||||||
|
|
||||||
/* Tasks are not created with a floating point context, but can be given a
|
/* Tasks are not created with a floating point context, but can be given a
|
||||||
floating point context after they have been created. A variable is stored as
|
* floating point context after they have been created. A variable is stored as
|
||||||
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
* part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||||
does not have an FPU context, or any other value if the task does have an FPU
|
* does not have an FPU context, or any other value if the task does have an FPU
|
||||||
context. */
|
* context. */
|
||||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||||
|
|
||||||
/* Constants required to setup the initial task context. */
|
/* Constants required to setup the initial task context. */
|
||||||
#define portSP_ELx ( ( StackType_t ) 0x01 )
|
#define portSP_ELx ( ( StackType_t ) 0x01 )
|
||||||
#define portSP_EL0 ( ( StackType_t ) 0x00 )
|
#define portSP_EL0 ( ( StackType_t ) 0x00 )
|
||||||
|
|
||||||
#if defined( GUEST )
|
#if defined( GUEST )
|
||||||
#define portEL1 ( ( StackType_t ) 0x04 )
|
#define portEL1 ( ( StackType_t ) 0x04 )
|
||||||
#define portINITIAL_PSTATE ( portEL1 | portSP_EL0 )
|
#define portINITIAL_PSTATE ( portEL1 | portSP_EL0 )
|
||||||
#else
|
#else
|
||||||
#define portEL3 ( ( StackType_t ) 0x0c )
|
#define portEL3 ( ( StackType_t ) 0x0c )
|
||||||
/* At the time of writing, the BSP only supports EL3. */
|
/* At the time of writing, the BSP only supports EL3. */
|
||||||
#define portINITIAL_PSTATE ( portEL3 | portSP_EL0 )
|
#define portINITIAL_PSTATE ( portEL3 | portSP_EL0 )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Masks all bits in the APSR other than the mode bits. */
|
/* Masks all bits in the APSR other than the mode bits. */
|
||||||
#define portAPSR_MODE_BITS_MASK ( 0x0C )
|
#define portAPSR_MODE_BITS_MASK ( 0x0C )
|
||||||
|
|
||||||
/* The I bit in the DAIF bits. */
|
/* The I bit in the DAIF bits. */
|
||||||
#define portDAIF_I ( 0x80 )
|
#define portDAIF_I ( 0x80 )
|
||||||
|
|
||||||
/* Macro to unmask all interrupt priorities. */
|
/* Macro to unmask all interrupt priorities. */
|
||||||
/* s3_0_c4_c6_0 is ICC_PMR_EL1. */
|
/* s3_0_c4_c6_0 is ICC_PMR_EL1. */
|
||||||
#define portCLEAR_INTERRUPT_MASK() \
|
#define portCLEAR_INTERRUPT_MASK() \
|
||||||
{ \
|
{ \
|
||||||
__asm volatile ( "MSR DAIFSET, #2 \n" \
|
__asm volatile ( "MSR DAIFSET, #2 \n" \
|
||||||
"DSB SY \n" \
|
"DSB SY \n" \
|
||||||
"ISB SY \n" \
|
"ISB SY \n" \
|
||||||
"MSR s3_0_c4_c6_0, %0 \n" \
|
"MSR s3_0_c4_c6_0, %0 \n" \
|
||||||
"DSB SY \n" \
|
"DSB SY \n" \
|
||||||
"ISB SY \n" \
|
"ISB SY \n" \
|
||||||
"MSR DAIFCLR, #2 \n" \
|
"MSR DAIFCLR, #2 \n" \
|
||||||
"DSB SY \n" \
|
"DSB SY \n" \
|
||||||
"ISB SY \n" \
|
"ISB SY \n" \
|
||||||
::"r"( portUNMASK_VALUE ) ); \
|
::"r" ( portUNMASK_VALUE ) ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -132,101 +132,103 @@ extern void vPortRestoreTaskContext( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* A variable is used to keep track of the critical section nesting. This
|
/* A variable is used to keep track of the critical section nesting. This
|
||||||
variable has to be stored as part of the task context and must be initialised to
|
* variable has to be stored as part of the task context and must be initialised to
|
||||||
a non zero value to ensure interrupts don't inadvertently become unmasked before
|
* a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||||
the scheduler starts. As it is stored as part of the task context it will
|
* the scheduler starts. As it is stored as part of the task context it will
|
||||||
automatically be set to 0 when the first task is started. */
|
* automatically be set to 0 when the first task is started. */
|
||||||
volatile uint64_t ullCriticalNesting = 9999ULL;
|
volatile uint64_t ullCriticalNesting = 9999ULL;
|
||||||
|
|
||||||
/* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero
|
/* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero
|
||||||
then floating point context must be saved and restored for the task. */
|
* then floating point context must be saved and restored for the task. */
|
||||||
uint64_t ullPortTaskHasFPUContext = pdFALSE;
|
uint64_t ullPortTaskHasFPUContext = pdFALSE;
|
||||||
|
|
||||||
/* Set to 1 to pend a context switch from an ISR. */
|
/* Set to 1 to pend a context switch from an ISR. */
|
||||||
uint64_t ullPortYieldRequired = pdFALSE;
|
uint64_t ullPortYieldRequired = pdFALSE;
|
||||||
|
|
||||||
/* Counts the interrupt nesting depth. A context switch is only performed if
|
/* Counts the interrupt nesting depth. A context switch is only performed if
|
||||||
if the nesting depth is 0. */
|
* if the nesting depth is 0. */
|
||||||
uint64_t ullPortInterruptNesting = 0;
|
uint64_t ullPortInterruptNesting = 0;
|
||||||
|
|
||||||
/* Used in the ASM code. */
|
/* Used in the ASM code. */
|
||||||
__attribute__(( used )) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
__attribute__( ( used ) ) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro. */
|
* expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First all the general purpose registers. */
|
/* First all the general purpose registers. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0101010101010101ULL; /* R1 */
|
*pxTopOfStack = 0x0101010101010101ULL; /* R1 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0303030303030303ULL; /* R3 */
|
*pxTopOfStack = 0x0303030303030303ULL; /* R3 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0202020202020202ULL; /* R2 */
|
*pxTopOfStack = 0x0202020202020202ULL; /* R2 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0505050505050505ULL; /* R5 */
|
*pxTopOfStack = 0x0505050505050505ULL; /* R5 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0404040404040404ULL; /* R4 */
|
*pxTopOfStack = 0x0404040404040404ULL; /* R4 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0707070707070707ULL; /* R7 */
|
*pxTopOfStack = 0x0707070707070707ULL; /* R7 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0606060606060606ULL; /* R6 */
|
*pxTopOfStack = 0x0606060606060606ULL; /* R6 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0909090909090909ULL; /* R9 */
|
*pxTopOfStack = 0x0909090909090909ULL; /* R9 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x0808080808080808ULL; /* R8 */
|
*pxTopOfStack = 0x0808080808080808ULL; /* R8 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1111111111111111ULL; /* R11 */
|
*pxTopOfStack = 0x1111111111111111ULL; /* R11 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1010101010101010ULL; /* R10 */
|
*pxTopOfStack = 0x1010101010101010ULL; /* R10 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1313131313131313ULL; /* R13 */
|
*pxTopOfStack = 0x1313131313131313ULL; /* R13 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1212121212121212ULL; /* R12 */
|
*pxTopOfStack = 0x1212121212121212ULL; /* R12 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1515151515151515ULL; /* R15 */
|
*pxTopOfStack = 0x1515151515151515ULL; /* R15 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1414141414141414ULL; /* R14 */
|
*pxTopOfStack = 0x1414141414141414ULL; /* R14 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1717171717171717ULL; /* R17 */
|
*pxTopOfStack = 0x1717171717171717ULL; /* R17 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1616161616161616ULL; /* R16 */
|
*pxTopOfStack = 0x1616161616161616ULL; /* R16 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1919191919191919ULL; /* R19 */
|
*pxTopOfStack = 0x1919191919191919ULL; /* R19 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x1818181818181818ULL; /* R18 */
|
*pxTopOfStack = 0x1818181818181818ULL; /* R18 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2121212121212121ULL; /* R21 */
|
*pxTopOfStack = 0x2121212121212121ULL; /* R21 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2020202020202020ULL; /* R20 */
|
*pxTopOfStack = 0x2020202020202020ULL; /* R20 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2323232323232323ULL; /* R23 */
|
*pxTopOfStack = 0x2323232323232323ULL; /* R23 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2222222222222222ULL; /* R22 */
|
*pxTopOfStack = 0x2222222222222222ULL; /* R22 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2525252525252525ULL; /* R25 */
|
*pxTopOfStack = 0x2525252525252525ULL; /* R25 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2424242424242424ULL; /* R24 */
|
*pxTopOfStack = 0x2424242424242424ULL; /* R24 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2727272727272727ULL; /* R27 */
|
*pxTopOfStack = 0x2727272727272727ULL; /* R27 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2626262626262626ULL; /* R26 */
|
*pxTopOfStack = 0x2626262626262626ULL; /* R26 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2929292929292929ULL; /* R29 */
|
*pxTopOfStack = 0x2929292929292929ULL; /* R29 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x2828282828282828ULL; /* R28 */
|
*pxTopOfStack = 0x2828282828282828ULL; /* R28 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */
|
*pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */
|
*pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
*pxTopOfStack = portINITIAL_PSTATE;
|
*pxTopOfStack = portINITIAL_PSTATE;
|
||||||
|
@ -236,13 +238,13 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||||
enabled. */
|
* enabled. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The task will start without a floating point context. A task that uses
|
/* The task will start without a floating point context. A task that uses
|
||||||
the floating point hardware must call vPortTaskUsesFPU() before executing
|
* the floating point hardware must call vPortTaskUsesFPU() before executing
|
||||||
any floating point instructions. */
|
* any floating point instructions. */
|
||||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -251,23 +253,26 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulAPSR;
|
uint32_t ulAPSR;
|
||||||
|
|
||||||
__asm volatile ( "MRS %0, CurrentEL" : "=r" ( ulAPSR ) );
|
__asm volatile ( "MRS %0, CurrentEL" : "=r" ( ulAPSR ) );
|
||||||
|
|
||||||
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
||||||
|
|
||||||
#if defined( GUEST )
|
#if defined( GUEST )
|
||||||
configASSERT( ulAPSR == portEL1 );
|
configASSERT( ulAPSR == portEL1 );
|
||||||
if( ulAPSR == portEL1 )
|
|
||||||
#else
|
if( ulAPSR == portEL1 )
|
||||||
configASSERT( ulAPSR == portEL3 );
|
#else
|
||||||
if( ulAPSR == portEL3 )
|
configASSERT( ulAPSR == portEL3 );
|
||||||
#endif
|
|
||||||
|
if( ulAPSR == portEL3 )
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/* Interrupts are turned off in the CPU itself to ensure a tick does
|
/* Interrupts are turned off in the CPU itself to ensure a tick does
|
||||||
not execute while the scheduler is being started. Interrupts are
|
* not execute while the scheduler is being started. Interrupts are
|
||||||
automatically turned back on in the CPU when the first task starts
|
* automatically turned back on in the CPU when the first task starts
|
||||||
executing. */
|
* executing. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. */
|
/* Start the timer that generates the tick ISR. */
|
||||||
|
@ -284,7 +289,7 @@ uint32_t ulAPSR;
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Not implemented in ports where there is nothing to return to.
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
Artificially force an assert. */
|
* Artificially force an assert. */
|
||||||
configASSERT( ullCriticalNesting == 1000ULL );
|
configASSERT( ullCriticalNesting == 1000ULL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -295,15 +300,15 @@ void vPortEnterCritical( void )
|
||||||
uxPortSetInterruptMask();
|
uxPortSetInterruptMask();
|
||||||
|
|
||||||
/* Now interrupts are disabled ullCriticalNesting can be accessed
|
/* Now interrupts are disabled ullCriticalNesting can be accessed
|
||||||
directly. Increment ullCriticalNesting to keep a count of how many times
|
* directly. Increment ullCriticalNesting to keep a count of how many times
|
||||||
portENTER_CRITICAL() has been called. */
|
* portENTER_CRITICAL() has been called. */
|
||||||
ullCriticalNesting++;
|
ullCriticalNesting++;
|
||||||
|
|
||||||
/* This is not the interrupt safe version of the enter critical function so
|
/* This is not the interrupt safe version of the enter critical function so
|
||||||
assert() if it is being called from an interrupt context. Only API
|
* assert() if it is being called from an interrupt context. Only API
|
||||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||||
the critical nesting count is 1 to protect against recursive calls if the
|
* the critical nesting count is 1 to protect against recursive calls if the
|
||||||
assert function also uses a critical section. */
|
* assert function also uses a critical section. */
|
||||||
if( ullCriticalNesting == 1ULL )
|
if( ullCriticalNesting == 1ULL )
|
||||||
{
|
{
|
||||||
configASSERT( ullPortInterruptNesting == 0 );
|
configASSERT( ullPortInterruptNesting == 0 );
|
||||||
|
@ -316,15 +321,15 @@ void vPortExitCritical( void )
|
||||||
if( ullCriticalNesting > portNO_CRITICAL_NESTING )
|
if( ullCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Decrement the nesting count as the critical section is being
|
/* Decrement the nesting count as the critical section is being
|
||||||
exited. */
|
* exited. */
|
||||||
ullCriticalNesting--;
|
ullCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then all interrupt
|
/* If the nesting level has reached zero then all interrupt
|
||||||
priorities must be re-enabled. */
|
* priorities must be re-enabled. */
|
||||||
if( ullCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ullCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Critical nesting has reached zero so all interrupt priorities
|
/* Critical nesting has reached zero so all interrupt priorities
|
||||||
should be unmasked. */
|
* should be unmasked. */
|
||||||
portCLEAR_INTERRUPT_MASK();
|
portCLEAR_INTERRUPT_MASK();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,25 +349,25 @@ void FreeRTOS_Tick_Handler( void )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Interrupts should not be enabled before this point. */
|
/* Interrupts should not be enabled before this point. */
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
uint32_t ulMaskBits;
|
uint32_t ulMaskBits;
|
||||||
|
|
||||||
__asm volatile( "MRS %0, DAIF" : "=r"( ulMaskBits ) :: "memory" );
|
__asm volatile ( "MRS %0, DAIF" : "=r" ( ulMaskBits )::"memory" );
|
||||||
configASSERT( ( ulMaskBits & portDAIF_I ) != 0 );
|
configASSERT( ( ulMaskBits & portDAIF_I ) != 0 );
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
/* Set interrupt mask before altering scheduler structures. The tick
|
/* Set interrupt mask before altering scheduler structures. The tick
|
||||||
handler runs at the lowest priority, so interrupts cannot already be masked,
|
* handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||||
so there is no need to save and restore the current mask value. It is
|
* so there is no need to save and restore the current mask value. It is
|
||||||
necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
* necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||||
updated. */
|
* updated. */
|
||||||
/* s3_0_c4_c6_0 is ICC_PMR_EL1. */
|
/* s3_0_c4_c6_0 is ICC_PMR_EL1. */
|
||||||
__asm volatile ( "MSR s3_0_c4_c6_0, %0 \n"
|
__asm volatile ( "MSR s3_0_c4_c6_0, %0 \n"
|
||||||
"DSB SY \n"
|
"DSB SY \n"
|
||||||
"ISB SY \n"
|
"ISB SY \n"
|
||||||
:: "r" ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) : "memory" );
|
::"r" ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) : "memory" );
|
||||||
|
|
||||||
/* Ok to enable interrupts after the interrupt source has been cleared. */
|
/* Ok to enable interrupts after the interrupt source has been cleared. */
|
||||||
configCLEAR_TICK_INTERRUPT();
|
configCLEAR_TICK_INTERRUPT();
|
||||||
|
@ -382,11 +387,11 @@ void FreeRTOS_Tick_Handler( void )
|
||||||
void vPortTaskUsesFPU( void )
|
void vPortTaskUsesFPU( void )
|
||||||
{
|
{
|
||||||
/* A task is registering the fact that it needs an FPU context. Set the
|
/* A task is registering the fact that it needs an FPU context. Set the
|
||||||
FPU flag (which is saved as part of the task context). */
|
* FPU flag (which is saved as part of the task context). */
|
||||||
ullPortTaskHasFPUContext = pdTRUE;
|
ullPortTaskHasFPUContext = pdTRUE;
|
||||||
|
|
||||||
/* Consider initialising the FPSR here - but probably not necessary in
|
/* Consider initialising the FPSR here - but probably not necessary in
|
||||||
AArch64. */
|
* AArch64. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -401,14 +406,15 @@ void vPortClearInterruptMask( UBaseType_t uxNewMaskValue )
|
||||||
|
|
||||||
UBaseType_t uxPortSetInterruptMask( void )
|
UBaseType_t uxPortSetInterruptMask( void )
|
||||||
{
|
{
|
||||||
uint32_t ulReturn;
|
uint32_t ulReturn;
|
||||||
uint64_t ullPMRValue;
|
uint64_t ullPMRValue;
|
||||||
|
|
||||||
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
||||||
updated. */
|
* updated. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
/* s3_0_c4_c6_0 is ICC_PMR_EL1. */
|
/* s3_0_c4_c6_0 is ICC_PMR_EL1. */
|
||||||
__asm volatile ( "MRS %0, s3_0_c4_c6_0" : "=r" ( ullPMRValue ) );
|
__asm volatile ( "MRS %0, s3_0_c4_c6_0" : "=r" ( ullPMRValue ) );
|
||||||
|
|
||||||
if( ullPMRValue == ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
if( ullPMRValue == ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
||||||
{
|
{
|
||||||
/* Interrupts were already masked. */
|
/* Interrupts were already masked. */
|
||||||
|
@ -421,7 +427,7 @@ uint64_t ullPMRValue;
|
||||||
__asm volatile ( "MSR s3_0_c4_c6_0, %0 \n"
|
__asm volatile ( "MSR s3_0_c4_c6_0, %0 \n"
|
||||||
"DSB SY \n"
|
"DSB SY \n"
|
||||||
"ISB SY \n"
|
"ISB SY \n"
|
||||||
:: "r" ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) : "memory" );
|
::"r" ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) : "memory" );
|
||||||
}
|
}
|
||||||
|
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
@ -430,27 +436,28 @@ uint64_t ullPMRValue;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
|
|
||||||
void vPortValidateInterruptPriority( void )
|
void vPortValidateInterruptPriority( void )
|
||||||
{
|
{
|
||||||
/* The following assertion will fail if a service routine (ISR) for
|
/* The following assertion will fail if a service routine (ISR) for
|
||||||
an interrupt that has been assigned a priority above
|
* an interrupt that has been assigned a priority above
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||||
function. ISR safe FreeRTOS API functions must *only* be called
|
* function. ISR safe FreeRTOS API functions must *only* be called
|
||||||
from interrupts that have been assigned a priority at or below
|
* from interrupts that have been assigned a priority at or below
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
|
*
|
||||||
Numerically low interrupt priority numbers represent logically high
|
* Numerically low interrupt priority numbers represent logically high
|
||||||
interrupt priorities, therefore the priority of the interrupt must
|
* interrupt priorities, therefore the priority of the interrupt must
|
||||||
be set to a value equal to or numerically *higher* than
|
* be set to a value equal to or numerically *higher* than
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
|
*
|
||||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||||
interrupt entry is as fast and simple as possible. */
|
* interrupt entry is as fast and simple as possible. */
|
||||||
uint64_t ullRunningInterruptPriority;
|
uint64_t ullRunningInterruptPriority;
|
||||||
/* s3_0_c12_c11_3 is ICC_RPR_EL1. */
|
/* s3_0_c12_c11_3 is ICC_RPR_EL1. */
|
||||||
__asm volatile ( "MRS %0, s3_0_c12_c11_3" : "=r" ( ullRunningInterruptPriority ) );
|
__asm volatile ( "MRS %0, s3_0_c12_c11_3" : "=r" ( ullRunningInterruptPriority ) );
|
||||||
|
|
||||||
configASSERT( ullRunningInterruptPriority >= ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
configASSERT( ullRunningInterruptPriority >= ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,57 +46,58 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE size_t
|
#define portSTACK_TYPE size_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef portBASE_TYPE BaseType_t;
|
typedef portBASE_TYPE BaseType_t;
|
||||||
typedef uint64_t UBaseType_t;
|
typedef uint64_t UBaseType_t;
|
||||||
|
|
||||||
typedef uint64_t TickType_t;
|
typedef uint64_t TickType_t;
|
||||||
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff )
|
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff )
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 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. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 16
|
#define portBYTE_ALIGNMENT 16
|
||||||
#define portPOINTER_SIZE_TYPE uint64_t
|
#define portPOINTER_SIZE_TYPE uint64_t
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
||||||
/* Called at the end of an ISR that can cause a context switch. */
|
/* Called at the end of an ISR that can cause a context switch. */
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired )\
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
{ \
|
{ \
|
||||||
extern uint64_t ullPortYieldRequired; \
|
extern uint64_t ullPortYieldRequired; \
|
||||||
\
|
\
|
||||||
if( xSwitchRequired != pdFALSE ) \
|
if( xSwitchRequired != pdFALSE ) \
|
||||||
{ \
|
{ \
|
||||||
ullPortYieldRequired = pdTRUE; \
|
ullPortYieldRequired = pdTRUE; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
#if defined( GUEST )
|
#if defined( GUEST )
|
||||||
#define portYIELD() __asm volatile ( "SVC 0" ::: "memory" )
|
#define portYIELD() __asm volatile ( "SVC 0" ::: "memory" )
|
||||||
#else
|
#else
|
||||||
#define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
|
#define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Critical section control
|
* Critical section control
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
@ -104,91 +105,91 @@ extern UBaseType_t uxPortSetInterruptMask( void );
|
||||||
extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue );
|
extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue );
|
||||||
extern void vPortInstallFreeRTOSVectorTable( void );
|
extern void vPortInstallFreeRTOSVectorTable( void );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
__asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \
|
__asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \
|
||||||
__asm volatile ( "DSB SY" ); \
|
__asm volatile ( "DSB SY" ); \
|
||||||
__asm volatile ( "ISB SY" );
|
__asm volatile ( "ISB SY" );
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
__asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \
|
__asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \
|
||||||
__asm volatile ( "DSB SY" ); \
|
__asm volatile ( "DSB SY" ); \
|
||||||
__asm volatile ( "ISB SY" );
|
__asm volatile ( "ISB SY" );
|
||||||
|
|
||||||
|
|
||||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||||
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
not required for this port but included in case common demo code that uses these
|
* not required for this port but included in case common demo code that uses these
|
||||||
macros is used. */
|
* macros is used. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
||||||
handler for whichever peripheral is used to generate the RTOS tick. */
|
* handler for whichever peripheral is used to generate the RTOS tick. */
|
||||||
void FreeRTOS_Tick_Handler( void );
|
void FreeRTOS_Tick_Handler( void );
|
||||||
|
|
||||||
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
||||||
before any floating point instructions are executed. */
|
* before any floating point instructions are executed. */
|
||||||
void vPortTaskUsesFPU( void );
|
void vPortTaskUsesFPU( void );
|
||||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||||
|
|
||||||
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
||||||
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
void vPortValidateInterruptPriority( void );
|
void vPortValidateInterruptPriority( void );
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
#endif /* configASSERT */
|
#endif /* configASSERT */
|
||||||
|
|
||||||
#define portNOP() __asm volatile( "NOP" )
|
#define portNOP() __asm volatile ( "NOP" )
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
|
|
||||||
/* The number of bits to shift for an interrupt priority is dependent on the
|
/* The number of bits to shift for an interrupt priority is dependent on the
|
||||||
number of bits implemented by the interrupt controller. */
|
* number of bits implemented by the interrupt controller. */
|
||||||
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
||||||
#define portPRIORITY_SHIFT 4
|
#define portPRIORITY_SHIFT 4
|
||||||
#define portMAX_BINARY_POINT_VALUE 3
|
#define portMAX_BINARY_POINT_VALUE 3
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
||||||
#define portPRIORITY_SHIFT 3
|
#define portPRIORITY_SHIFT 3
|
||||||
#define portMAX_BINARY_POINT_VALUE 2
|
#define portMAX_BINARY_POINT_VALUE 2
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
||||||
#define portPRIORITY_SHIFT 2
|
#define portPRIORITY_SHIFT 2
|
||||||
#define portMAX_BINARY_POINT_VALUE 1
|
#define portMAX_BINARY_POINT_VALUE 1
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
||||||
#define portPRIORITY_SHIFT 1
|
#define portPRIORITY_SHIFT 1
|
||||||
#define portMAX_BINARY_POINT_VALUE 0
|
#define portMAX_BINARY_POINT_VALUE 0
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
||||||
#define portPRIORITY_SHIFT 0
|
#define portPRIORITY_SHIFT 0
|
||||||
#define portMAX_BINARY_POINT_VALUE 0
|
#define portMAX_BINARY_POINT_VALUE 0
|
||||||
#else
|
#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||||
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
||||||
#endif
|
#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||||
|
|
||||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -35,123 +35,123 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
|
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
|
||||||
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error "configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
|
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
|
||||||
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error "configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
||||||
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error "configUNIQUE_INTERRUPT_PRIORITIES must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configSETUP_TICK_INTERRUPT
|
#ifndef configSETUP_TICK_INTERRUPT
|
||||||
#error configSETUP_TICK_INTERRUPT() must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error "configSETUP_TICK_INTERRUPT() must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||||
#endif /* configSETUP_TICK_INTERRUPT */
|
#endif /* configSETUP_TICK_INTERRUPT */
|
||||||
|
|
||||||
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0
|
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY > configUNIQUE_INTERRUPT_PRIORITIES
|
#if configMAX_API_CALL_INTERRUPT_PRIORITY > configUNIQUE_INTERRUPT_PRIORITIES
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority
|
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if( configMAX_PRIORITIES > 32 )
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error "configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice."
|
||||||
#endif
|
#endif
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
/* In case security extensions are implemented. */
|
/* In case security extensions are implemented. */
|
||||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
|
#if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
|
#error "configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
||||||
portmacro.h. */
|
* portmacro.h. */
|
||||||
#ifndef configCLEAR_TICK_INTERRUPT
|
#ifndef configCLEAR_TICK_INTERRUPT
|
||||||
#define configCLEAR_TICK_INTERRUPT()
|
#define configCLEAR_TICK_INTERRUPT()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* A critical section is exited when the critical section nesting count reaches
|
/* A critical section is exited when the critical section nesting count reaches
|
||||||
this value. */
|
* this value. */
|
||||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||||
|
|
||||||
/* In all GICs 255 can be written to the priority mask register to unmask all
|
/* In all GICs 255 can be written to the priority mask register to unmask all
|
||||||
(but the lowest) interrupt priority. */
|
* (but the lowest) interrupt priority. */
|
||||||
#define portUNMASK_VALUE ( 0xFFUL )
|
#define portUNMASK_VALUE ( 0xFFUL )
|
||||||
|
|
||||||
/* Tasks are not created with a floating point context, but can be given a
|
/* Tasks are not created with a floating point context, but can be given a
|
||||||
floating point context after they have been created. A variable is stored as
|
* floating point context after they have been created. A variable is stored as
|
||||||
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
* part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||||
does not have an FPU context, or any other value if the task does have an FPU
|
* does not have an FPU context, or any other value if the task does have an FPU
|
||||||
context. */
|
* context. */
|
||||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||||
|
|
||||||
/* Constants required to setup the initial task context. */
|
/* Constants required to setup the initial task context. */
|
||||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, IRQ enabled FIQ enabled. */
|
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, IRQ enabled FIQ enabled. */
|
||||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||||
#define portINTERRUPT_ENABLE_BIT ( 0x80UL )
|
#define portINTERRUPT_ENABLE_BIT ( 0x80UL )
|
||||||
#define portTHUMB_MODE_ADDRESS ( 0x01UL )
|
#define portTHUMB_MODE_ADDRESS ( 0x01UL )
|
||||||
|
|
||||||
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
||||||
point is zero. */
|
* point is zero. */
|
||||||
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
||||||
|
|
||||||
/* Masks all bits in the APSR other than the mode bits. */
|
/* Masks all bits in the APSR other than the mode bits. */
|
||||||
#define portAPSR_MODE_BITS_MASK ( 0x1F )
|
#define portAPSR_MODE_BITS_MASK ( 0x1F )
|
||||||
|
|
||||||
/* The value of the mode bits in the APSR when the CPU is executing in user
|
/* The value of the mode bits in the APSR when the CPU is executing in user
|
||||||
mode. */
|
* mode. */
|
||||||
#define portAPSR_USER_MODE ( 0x10 )
|
#define portAPSR_USER_MODE ( 0x10 )
|
||||||
|
|
||||||
/* The critical section macros only mask interrupts up to an application
|
/* The critical section macros only mask interrupts up to an application
|
||||||
determined priority level. Sometimes it is necessary to turn interrupt off in
|
* determined priority level. Sometimes it is necessary to turn interrupt off in
|
||||||
the CPU itself before modifying certain hardware registers. */
|
* the CPU itself before modifying certain hardware registers. */
|
||||||
#define portCPU_IRQ_DISABLE() \
|
#define portCPU_IRQ_DISABLE() \
|
||||||
__asm volatile ( "CPSID i" ::: "memory" ); \
|
__asm volatile ( "CPSID i" ::: "memory" ); \
|
||||||
__asm volatile ( "DSB" ); \
|
__asm volatile ( "DSB" ); \
|
||||||
__asm volatile ( "ISB" );
|
__asm volatile ( "ISB" );
|
||||||
|
|
||||||
#define portCPU_IRQ_ENABLE() \
|
#define portCPU_IRQ_ENABLE() \
|
||||||
__asm volatile ( "CPSIE i" ::: "memory" ); \
|
__asm volatile ( "CPSIE i" ::: "memory" ); \
|
||||||
__asm volatile ( "DSB" ); \
|
__asm volatile ( "DSB" ); \
|
||||||
__asm volatile ( "ISB" );
|
__asm volatile ( "ISB" );
|
||||||
|
|
||||||
|
|
||||||
/* Macro to unmask all interrupt priorities. */
|
/* Macro to unmask all interrupt priorities. */
|
||||||
#define portCLEAR_INTERRUPT_MASK() \
|
#define portCLEAR_INTERRUPT_MASK() \
|
||||||
{ \
|
{ \
|
||||||
portCPU_IRQ_DISABLE(); \
|
portCPU_IRQ_DISABLE(); \
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
||||||
__asm volatile ( "DSB \n" \
|
__asm volatile ( "DSB \n" \
|
||||||
"ISB \n" ); \
|
"ISB \n" ); \
|
||||||
portCPU_IRQ_ENABLE(); \
|
portCPU_IRQ_ENABLE(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
|
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
|
||||||
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
||||||
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
|
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
|
||||||
|
|
||||||
/* Let the user override the pre-loading of the initial LR with the address of
|
/* Let the user override the pre-loading of the initial LR with the address of
|
||||||
prvTaskExitError() in case it messes up unwinding of the stack in the
|
* prvTaskExitError() in case it messes up unwinding of the stack in the
|
||||||
debugger. */
|
* debugger. */
|
||||||
#ifdef configTASK_RETURN_ADDRESS
|
#ifdef configTASK_RETURN_ADDRESS
|
||||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||||
#else
|
#else
|
||||||
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The space on the stack required to hold the FPU registers. This is 32 64-bit
|
/* The space on the stack required to hold the FPU registers. This is 32 64-bit
|
||||||
registers, plus a 32-bit status register. */
|
* registers, plus a 32-bit status register. */
|
||||||
#define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 1 )
|
#define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 1 )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -185,47 +185,49 @@ static void prvTaskExitError( void );
|
||||||
* FPU registers to be saved on interrupt entry their IRQ handler must be
|
* FPU registers to be saved on interrupt entry their IRQ handler must be
|
||||||
* called vApplicationIRQHandler().
|
* called vApplicationIRQHandler().
|
||||||
*/
|
*/
|
||||||
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__((weak) );
|
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__( ( weak ) );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* A variable is used to keep track of the critical section nesting. This
|
/* A variable is used to keep track of the critical section nesting. This
|
||||||
variable has to be stored as part of the task context and must be initialised to
|
* variable has to be stored as part of the task context and must be initialised to
|
||||||
a non zero value to ensure interrupts don't inadvertently become unmasked before
|
* a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||||
the scheduler starts. As it is stored as part of the task context it will
|
* the scheduler starts. As it is stored as part of the task context it will
|
||||||
automatically be set to 0 when the first task is started. */
|
* automatically be set to 0 when the first task is started. */
|
||||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
/* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then
|
/* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then
|
||||||
a floating point context must be saved and restored for the task. */
|
* a floating point context must be saved and restored for the task. */
|
||||||
volatile uint32_t ulPortTaskHasFPUContext = pdFALSE;
|
volatile uint32_t ulPortTaskHasFPUContext = pdFALSE;
|
||||||
|
|
||||||
/* Set to 1 to pend a context switch from an ISR. */
|
/* Set to 1 to pend a context switch from an ISR. */
|
||||||
volatile uint32_t ulPortYieldRequired = pdFALSE;
|
volatile uint32_t ulPortYieldRequired = pdFALSE;
|
||||||
|
|
||||||
/* Counts the interrupt nesting depth. A context switch is only performed if
|
/* Counts the interrupt nesting depth. A context switch is only performed if
|
||||||
if the nesting depth is 0. */
|
* if the nesting depth is 0. */
|
||||||
volatile uint32_t ulPortInterruptNesting = 0UL;
|
volatile uint32_t ulPortInterruptNesting = 0UL;
|
||||||
|
|
||||||
/* Used in the asm file. */
|
/* Used in the asm file. */
|
||||||
__attribute__(( used )) const uint32_t ulICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;
|
__attribute__( ( used ) ) const uint32_t ulICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;
|
||||||
__attribute__(( used )) const uint32_t ulICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;
|
__attribute__( ( used ) ) const uint32_t ulICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;
|
||||||
__attribute__(( used )) const uint32_t ulICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;
|
__attribute__( ( used ) ) const uint32_t ulICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;
|
||||||
__attribute__(( used )) const uint32_t ulMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
__attribute__( ( used ) ) const uint32_t ulMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro.
|
* expected by the portRESTORE_CONTEXT() macro.
|
||||||
|
*
|
||||||
The fist real value on the stack is the status register, which is set for
|
* The fist real value on the stack is the status register, which is set for
|
||||||
system mode, with interrupts enabled. A few NULLs are added first to ensure
|
* system mode, with interrupts enabled. A few NULLs are added first to ensure
|
||||||
GDB does not try decoding a non-existent return address. */
|
* GDB does not try decoding a non-existent return address. */
|
||||||
*pxTopOfStack = ( StackType_t ) NULL;
|
*pxTopOfStack = ( StackType_t ) NULL;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) NULL;
|
*pxTopOfStack = ( StackType_t ) NULL;
|
||||||
|
@ -247,51 +249,51 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Next all the registers other than the stack pointer. */
|
/* Next all the registers other than the stack pointer. */
|
||||||
*pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* R14 */
|
*pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* R14 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||||
enabled. */
|
* enabled. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||||
|
|
||||||
#if( configUSE_TASK_FPU_SUPPORT == 1 )
|
#if ( configUSE_TASK_FPU_SUPPORT == 1 )
|
||||||
{
|
{
|
||||||
/* The task will start without a floating point context. A task that
|
/* The task will start without a floating point context. A task that
|
||||||
uses the floating point hardware must call vPortTaskUsesFPU() before
|
* uses the floating point hardware must call vPortTaskUsesFPU() before
|
||||||
executing any floating point instructions. */
|
* executing any floating point instructions. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||||
}
|
}
|
||||||
#elif( configUSE_TASK_FPU_SUPPORT == 2 )
|
#elif ( configUSE_TASK_FPU_SUPPORT == 2 )
|
||||||
{
|
{
|
||||||
/* The task will start with a floating point context. Leave enough
|
/* The task will start with a floating point context. Leave enough
|
||||||
space for the registers - and ensure they are initialised to 0. */
|
* space for the registers - and ensure they are initialised to 0. */
|
||||||
pxTopOfStack -= portFPU_REGISTER_WORDS;
|
pxTopOfStack -= portFPU_REGISTER_WORDS;
|
||||||
memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
|
memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
|
||||||
|
|
||||||
|
@ -299,11 +301,11 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
*pxTopOfStack = pdTRUE;
|
*pxTopOfStack = pdTRUE;
|
||||||
ulPortTaskHasFPUContext = pdTRUE;
|
ulPortTaskHasFPUContext = pdTRUE;
|
||||||
}
|
}
|
||||||
#else
|
#else /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
|
||||||
{
|
{
|
||||||
#error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined.
|
#error "Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined."
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
|
@ -312,34 +314,37 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
static void prvTaskExitError( void )
|
static void prvTaskExitError( void )
|
||||||
{
|
{
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* 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
|
* its caller as there is nothing to return to. If a task wants to exit it
|
||||||
should instead call vTaskDelete( NULL ).
|
* should instead call vTaskDelete( NULL ).
|
||||||
|
*
|
||||||
Artificially force an assert() to be triggered if configASSERT() is
|
* Artificially force an assert() to be triggered if configASSERT() is
|
||||||
defined, then stop here so application writers can catch the error. */
|
* defined, then stop here so application writers can catch the error. */
|
||||||
configASSERT( ulPortInterruptNesting == ~0UL );
|
configASSERT( ulPortInterruptNesting == ~0UL );
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
for( ;; );
|
|
||||||
|
for( ; ; )
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulAPSR;
|
uint32_t ulAPSR;
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint8_t ucOriginalPriority;
|
volatile uint8_t ucOriginalPriority;
|
||||||
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );
|
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine how many priority bits are implemented in the GIC.
|
/* Determine how many priority bits are implemented in the GIC.
|
||||||
|
*
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
* Save the interrupt priority value that is about to be clobbered. */
|
||||||
ucOriginalPriority = *pucFirstUserPriorityRegister;
|
ucOriginalPriority = *pucFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to
|
/* Determine the number of priority bits available. First write to
|
||||||
all possible bits. */
|
* all possible bits. */
|
||||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -352,35 +357,35 @@ uint32_t ulAPSR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
||||||
value. */
|
* value. */
|
||||||
configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY );
|
configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY );
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
value. */
|
* value. */
|
||||||
*pucFirstUserPriorityRegister = ucOriginalPriority;
|
*pucFirstUserPriorityRegister = ucOriginalPriority;
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
|
|
||||||
/* Only continue if the CPU is not in User mode. The CPU must be in a
|
/* Only continue if the CPU is not in User mode. The CPU must be in a
|
||||||
Privileged mode for the scheduler to start. */
|
* Privileged mode for the scheduler to start. */
|
||||||
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) :: "memory" );
|
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR )::"memory" );
|
||||||
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
||||||
configASSERT( ulAPSR != portAPSR_USER_MODE );
|
configASSERT( ulAPSR != portAPSR_USER_MODE );
|
||||||
|
|
||||||
if( ulAPSR != portAPSR_USER_MODE )
|
if( ulAPSR != portAPSR_USER_MODE )
|
||||||
{
|
{
|
||||||
/* Only continue if the binary point value is set to its lowest possible
|
/* Only continue if the binary point value is set to its lowest possible
|
||||||
setting. See the comments in vPortValidateInterruptPriority() below for
|
* setting. See the comments in vPortValidateInterruptPriority() below for
|
||||||
more information. */
|
* more information. */
|
||||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||||
|
|
||||||
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
||||||
{
|
{
|
||||||
/* Interrupts are turned off in the CPU itself to ensure tick does
|
/* Interrupts are turned off in the CPU itself to ensure tick does
|
||||||
not execute while the scheduler is being started. Interrupts are
|
* not execute while the scheduler is being started. Interrupts are
|
||||||
automatically turned back on in the CPU when the first task starts
|
* automatically turned back on in the CPU when the first task starts
|
||||||
executing. */
|
* executing. */
|
||||||
portCPU_IRQ_DISABLE();
|
portCPU_IRQ_DISABLE();
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. */
|
/* Start the timer that generates the tick ISR. */
|
||||||
|
@ -392,10 +397,10 @@ uint32_t ulAPSR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Will only get here if vTaskStartScheduler() was called with the CPU in
|
/* Will only get here if vTaskStartScheduler() was called with the CPU in
|
||||||
a non-privileged mode or the binary point register was not set to its lowest
|
* a non-privileged mode or the binary point register was not set to its lowest
|
||||||
possible value. prvTaskExitError() is referenced to prevent a compiler
|
* possible value. prvTaskExitError() is referenced to prevent a compiler
|
||||||
warning about it being defined but not referenced in the case that the user
|
* warning about it being defined but not referenced in the case that the user
|
||||||
defines their own exit address. */
|
* defines their own exit address. */
|
||||||
( void ) prvTaskExitError;
|
( void ) prvTaskExitError;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -404,7 +409,7 @@ uint32_t ulAPSR;
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Not implemented in ports where there is nothing to return to.
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
Artificially force an assert. */
|
* Artificially force an assert. */
|
||||||
configASSERT( ulCriticalNesting == 1000UL );
|
configASSERT( ulCriticalNesting == 1000UL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -414,16 +419,16 @@ void vPortEnterCritical( void )
|
||||||
/* Mask interrupts up to the max syscall interrupt priority. */
|
/* Mask interrupts up to the max syscall interrupt priority. */
|
||||||
ulPortSetInterruptMask();
|
ulPortSetInterruptMask();
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now that interrupts are disabled, ulCriticalNesting can be accessed
|
||||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
portENTER_CRITICAL() has been called. */
|
* portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
|
|
||||||
/* This is not the interrupt safe version of the enter critical function so
|
/* This is not the interrupt safe version of the enter critical function so
|
||||||
assert() if it is being called from an interrupt context. Only API
|
* assert() if it is being called from an interrupt context. Only API
|
||||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||||
the critical nesting count is 1 to protect against recursive calls if the
|
* the critical nesting count is 1 to protect against recursive calls if the
|
||||||
assert function also uses a critical section. */
|
* assert function also uses a critical section. */
|
||||||
if( ulCriticalNesting == 1 )
|
if( ulCriticalNesting == 1 )
|
||||||
{
|
{
|
||||||
configASSERT( ulPortInterruptNesting == 0 );
|
configASSERT( ulPortInterruptNesting == 0 );
|
||||||
|
@ -436,15 +441,15 @@ void vPortExitCritical( void )
|
||||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Decrement the nesting count as the critical section is being
|
/* Decrement the nesting count as the critical section is being
|
||||||
exited. */
|
* exited. */
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then all interrupt
|
/* If the nesting level has reached zero then all interrupt
|
||||||
priorities must be re-enabled. */
|
* priorities must be re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Critical nesting has reached zero so all interrupt priorities
|
/* Critical nesting has reached zero so all interrupt priorities
|
||||||
should be unmasked. */
|
* should be unmasked. */
|
||||||
portCLEAR_INTERRUPT_MASK();
|
portCLEAR_INTERRUPT_MASK();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -454,14 +459,14 @@ void vPortExitCritical( void )
|
||||||
void FreeRTOS_Tick_Handler( void )
|
void FreeRTOS_Tick_Handler( void )
|
||||||
{
|
{
|
||||||
/* Set interrupt mask before altering scheduler structures. The tick
|
/* Set interrupt mask before altering scheduler structures. The tick
|
||||||
handler runs at the lowest priority, so interrupts cannot already be masked,
|
* handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||||
so there is no need to save and restore the current mask value. It is
|
* so there is no need to save and restore the current mask value. It is
|
||||||
necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
* necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||||
updated. */
|
* updated. */
|
||||||
portCPU_IRQ_DISABLE();
|
portCPU_IRQ_DISABLE();
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
__asm volatile ( "dsb \n"
|
__asm volatile ( "dsb \n"
|
||||||
"isb \n" ::: "memory" );
|
"isb \n" ::: "memory" );
|
||||||
portCPU_IRQ_ENABLE();
|
portCPU_IRQ_ENABLE();
|
||||||
|
|
||||||
/* Increment the RTOS tick. */
|
/* Increment the RTOS tick. */
|
||||||
|
@ -476,18 +481,18 @@ void FreeRTOS_Tick_Handler( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configUSE_TASK_FPU_SUPPORT != 2 )
|
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
|
||||||
|
|
||||||
void vPortTaskUsesFPU( void )
|
void vPortTaskUsesFPU( void )
|
||||||
{
|
{
|
||||||
uint32_t ulInitialFPSCR = 0;
|
uint32_t ulInitialFPSCR = 0;
|
||||||
|
|
||||||
/* A task is registering the fact that it needs an FPU context. Set the
|
/* A task is registering the fact that it needs an FPU context. Set the
|
||||||
FPU flag (which is saved as part of the task context). */
|
* FPU flag (which is saved as part of the task context). */
|
||||||
ulPortTaskHasFPUContext = pdTRUE;
|
ulPortTaskHasFPUContext = pdTRUE;
|
||||||
|
|
||||||
/* Initialise the floating point status register. */
|
/* Initialise the floating point status register. */
|
||||||
__asm volatile ( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) : "memory" );
|
__asm volatile ( "FMXR FPSCR, %0" ::"r" ( ulInitialFPSCR ) : "memory" );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configUSE_TASK_FPU_SUPPORT */
|
#endif /* configUSE_TASK_FPU_SUPPORT */
|
||||||
|
@ -504,11 +509,12 @@ void vPortClearInterruptMask( uint32_t ulNewMaskValue )
|
||||||
|
|
||||||
uint32_t ulPortSetInterruptMask( void )
|
uint32_t ulPortSetInterruptMask( void )
|
||||||
{
|
{
|
||||||
uint32_t ulReturn;
|
uint32_t ulReturn;
|
||||||
|
|
||||||
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
||||||
updated. */
|
* updated. */
|
||||||
portCPU_IRQ_DISABLE();
|
portCPU_IRQ_DISABLE();
|
||||||
|
|
||||||
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
||||||
{
|
{
|
||||||
/* Interrupts were already masked. */
|
/* Interrupts were already masked. */
|
||||||
|
@ -518,45 +524,46 @@ uint32_t ulReturn;
|
||||||
{
|
{
|
||||||
ulReturn = pdFALSE;
|
ulReturn = pdFALSE;
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
__asm volatile ( "dsb \n"
|
__asm volatile ( "dsb \n"
|
||||||
"isb \n" ::: "memory" );
|
"isb \n" ::: "memory" );
|
||||||
}
|
}
|
||||||
|
|
||||||
portCPU_IRQ_ENABLE();
|
portCPU_IRQ_ENABLE();
|
||||||
|
|
||||||
return ulReturn;
|
return ulReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
|
|
||||||
void vPortValidateInterruptPriority( void )
|
void vPortValidateInterruptPriority( void )
|
||||||
{
|
{
|
||||||
/* The following assertion will fail if a service routine (ISR) for
|
/* The following assertion will fail if a service routine (ISR) for
|
||||||
an interrupt that has been assigned a priority above
|
* an interrupt that has been assigned a priority above
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||||
function. ISR safe FreeRTOS API functions must *only* be called
|
* function. ISR safe FreeRTOS API functions must *only* be called
|
||||||
from interrupts that have been assigned a priority at or below
|
* from interrupts that have been assigned a priority at or below
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
|
*
|
||||||
Numerically low interrupt priority numbers represent logically high
|
* Numerically low interrupt priority numbers represent logically high
|
||||||
interrupt priorities, therefore the priority of the interrupt must
|
* interrupt priorities, therefore the priority of the interrupt must
|
||||||
be set to a value equal to or numerically *higher* than
|
* be set to a value equal to or numerically *higher* than
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
|
*
|
||||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||||
interrupt entry is as fast and simple as possible. */
|
* interrupt entry is as fast and simple as possible. */
|
||||||
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
||||||
|
|
||||||
/* Priority grouping: The interrupt controller (GIC) allows the bits
|
/* Priority grouping: The interrupt controller (GIC) allows the bits
|
||||||
that define each interrupt's priority to be split between bits that
|
* that define each interrupt's priority to be split between bits that
|
||||||
define the interrupt's pre-emption priority bits and bits that define
|
* define the interrupt's pre-emption priority bits and bits that define
|
||||||
the interrupt's sub-priority. For simplicity all bits must be defined
|
* the interrupt's sub-priority. For simplicity all bits must be defined
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
* to be pre-emption priority bits. The following assertion will fail if
|
||||||
this is not the case (if some bits represent a sub-priority).
|
* this is not the case (if some bits represent a sub-priority).
|
||||||
|
*
|
||||||
The priority grouping is configured by the GIC's binary point register
|
* The priority grouping is configured by the GIC's binary point register
|
||||||
(ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
* (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
||||||
possible value (which may be above 0). */
|
* possible value (which may be above 0). */
|
||||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,54 +46,54 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 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. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
||||||
/* Called at the end of an ISR that can cause a context switch. */
|
/* Called at the end of an ISR that can cause a context switch. */
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired )\
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
{ \
|
{ \
|
||||||
extern uint32_t ulPortYieldRequired; \
|
extern uint32_t ulPortYieldRequired; \
|
||||||
\
|
\
|
||||||
if( xSwitchRequired != pdFALSE ) \
|
if( xSwitchRequired != pdFALSE ) \
|
||||||
{ \
|
{ \
|
||||||
ulPortYieldRequired = pdTRUE; \
|
ulPortYieldRequired = pdTRUE; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
#define portYIELD() __asm volatile ( "SWI 0" ::: "memory" );
|
#define portYIELD() __asm volatile ( "SWI 0" ::: "memory" );
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Critical section control
|
* Critical section control
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
@ -102,105 +102,106 @@ extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
||||||
extern void vPortInstallFreeRTOSVectorTable( void );
|
extern void vPortInstallFreeRTOSVectorTable( void );
|
||||||
|
|
||||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||||
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
not required for this port but included in case common demo code that uses these
|
* not required for this port but included in case common demo code that uses these
|
||||||
macros is used. */
|
* macros is used. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
||||||
handler for whichever peripheral is used to generate the RTOS tick. */
|
* handler for whichever peripheral is used to generate the RTOS tick. */
|
||||||
void FreeRTOS_Tick_Handler( void );
|
void FreeRTOS_Tick_Handler( void );
|
||||||
|
|
||||||
/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are
|
/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are
|
||||||
created without an FPU context and must call vPortTaskUsesFPU() to give
|
* created without an FPU context and must call vPortTaskUsesFPU() to give
|
||||||
themselves an FPU context before using any FPU instructions. If
|
* themselves an FPU context before using any FPU instructions. If
|
||||||
configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context
|
* configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context
|
||||||
by default. */
|
* by default. */
|
||||||
#if( configUSE_TASK_FPU_SUPPORT != 2 )
|
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
|
||||||
void vPortTaskUsesFPU( void );
|
void vPortTaskUsesFPU( void );
|
||||||
#else
|
#else
|
||||||
/* Each task has an FPU context already, so define this function away to
|
|
||||||
nothing to prevent it being called accidentally. */
|
/* Each task has an FPU context already, so define this function away to
|
||||||
|
* nothing to prevent it being called accidentally. */
|
||||||
#define vPortTaskUsesFPU()
|
#define vPortTaskUsesFPU()
|
||||||
#endif
|
#endif
|
||||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||||
|
|
||||||
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
||||||
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __builtin_clz( uxReadyPriorities ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __builtin_clz( uxReadyPriorities ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
void vPortValidateInterruptPriority( void );
|
void vPortValidateInterruptPriority( void );
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
#endif /* configASSERT */
|
#endif /* configASSERT */
|
||||||
|
|
||||||
#define portNOP() __asm volatile( "NOP" )
|
#define portNOP() __asm volatile ( "NOP" )
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
|
|
||||||
/* The number of bits to shift for an interrupt priority is dependent on the
|
/* The number of bits to shift for an interrupt priority is dependent on the
|
||||||
number of bits implemented by the interrupt controller. */
|
* number of bits implemented by the interrupt controller. */
|
||||||
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
||||||
#define portPRIORITY_SHIFT 4
|
#define portPRIORITY_SHIFT 4
|
||||||
#define portMAX_BINARY_POINT_VALUE 3
|
#define portMAX_BINARY_POINT_VALUE 3
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
||||||
#define portPRIORITY_SHIFT 3
|
#define portPRIORITY_SHIFT 3
|
||||||
#define portMAX_BINARY_POINT_VALUE 2
|
#define portMAX_BINARY_POINT_VALUE 2
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
||||||
#define portPRIORITY_SHIFT 2
|
#define portPRIORITY_SHIFT 2
|
||||||
#define portMAX_BINARY_POINT_VALUE 1
|
#define portMAX_BINARY_POINT_VALUE 1
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
||||||
#define portPRIORITY_SHIFT 1
|
#define portPRIORITY_SHIFT 1
|
||||||
#define portMAX_BINARY_POINT_VALUE 0
|
#define portMAX_BINARY_POINT_VALUE 0
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
||||||
#define portPRIORITY_SHIFT 0
|
#define portPRIORITY_SHIFT 0
|
||||||
#define portMAX_BINARY_POINT_VALUE 0
|
#define portMAX_BINARY_POINT_VALUE 0
|
||||||
#else
|
#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||||
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
||||||
#endif
|
#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||||
|
|
||||||
/* Interrupt controller access addresses. */
|
/* Interrupt controller access addresses. */
|
||||||
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
||||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
||||||
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
||||||
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
||||||
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
||||||
|
|
||||||
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
||||||
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
||||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
||||||
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
||||||
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
||||||
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
||||||
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
||||||
|
|
||||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -205,20 +205,20 @@ void vPortStartFirstTask( void )
|
||||||
* Not all M0 parts have the application vector table at address 0. */
|
* Not all M0 parts have the application vector table at address 0. */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n"/* Obtain location of pxCurrentTCB. */
|
" ldr r2, pxCurrentTCBConst2 \n" /* Obtain location of pxCurrentTCB. */
|
||||||
" ldr r3, [r2] \n"
|
" ldr r3, [r2] \n"
|
||||||
" ldr r0, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" adds r0, #32 \n"/* Discard everything up to r0. */
|
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||||
" movs r0, #2 \n"/* Switch to the psp stack. */
|
" movs r0, #2 \n" /* Switch to the psp stack. */
|
||||||
" msr CONTROL, r0 \n"
|
" msr CONTROL, r0 \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" pop {r0-r5} \n"/* Pop the registers that are saved automatically. */
|
" pop {r0-r5} \n" /* Pop the registers that are saved automatically. */
|
||||||
" mov lr, r5 \n"/* lr is now in r5. */
|
" mov lr, r5 \n" /* lr is now in r5. */
|
||||||
" pop {r3} \n"/* Return address is now in r3. */
|
" pop {r3} \n" /* Return address is now in r3. */
|
||||||
" pop {r2} \n"/* Pop and discard XPSR. */
|
" pop {r2} \n" /* Pop and discard XPSR. */
|
||||||
" cpsie i \n"/* The first task has its context and interrupts can be enabled. */
|
" cpsie i \n" /* The first task has its context and interrupts can be enabled. */
|
||||||
" bx r3 \n"/* Finally, jump to the user defined task code. */
|
" bx r3 \n" /* Finally, jump to the user defined task code. */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst2: .word pxCurrentTCB "
|
"pxCurrentTCBConst2: .word pxCurrentTCB "
|
||||||
|
@ -330,13 +330,13 @@ void xPortPendSVHandler( void )
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" mrs r0, psp \n"
|
" mrs r0, psp \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */
|
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
||||||
" ldr r2, [r3] \n"
|
" ldr r2, [r3] \n"
|
||||||
" \n"
|
" \n"
|
||||||
" subs r0, r0, #32 \n"/* Make space for the remaining low registers. */
|
" subs r0, r0, #32 \n" /* Make space for the remaining low registers. */
|
||||||
" str r0, [r2] \n"/* Save the new top of stack. */
|
" str r0, [r2] \n" /* Save the new top of stack. */
|
||||||
" stmia r0!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */
|
" stmia r0!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */
|
||||||
" mov r4, r8 \n"/* Store the high registers. */
|
" mov r4, r8 \n" /* Store the high registers. */
|
||||||
" mov r5, r9 \n"
|
" mov r5, r9 \n"
|
||||||
" mov r6, r10 \n"
|
" mov r6, r10 \n"
|
||||||
" mov r7, r11 \n"
|
" mov r7, r11 \n"
|
||||||
|
@ -346,21 +346,21 @@ void xPortPendSVHandler( void )
|
||||||
" cpsid i \n"
|
" cpsid i \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" cpsie i \n"
|
" cpsie i \n"
|
||||||
" pop {r2, r3} \n"/* lr goes in r3. r2 now holds tcb pointer. */
|
" pop {r2, r3} \n" /* lr goes in r3. r2 now holds tcb pointer. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r1, [r2] \n"
|
" ldr r1, [r2] \n"
|
||||||
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" adds r0, r0, #16 \n"/* Move to the high registers. */
|
" adds r0, r0, #16 \n" /* Move to the high registers. */
|
||||||
" ldmia r0!, {r4-r7} \n"/* Pop the high registers. */
|
" ldmia r0!, {r4-r7} \n" /* Pop the high registers. */
|
||||||
" mov r8, r4 \n"
|
" mov r8, r4 \n"
|
||||||
" mov r9, r5 \n"
|
" mov r9, r5 \n"
|
||||||
" mov r10, r6 \n"
|
" mov r10, r6 \n"
|
||||||
" mov r11, r7 \n"
|
" mov r11, r7 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" msr psp, r0 \n"/* Remember the new top of stack for the task. */
|
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
||||||
" \n"
|
" \n"
|
||||||
" subs r0, r0, #32 \n"/* Go back for the low registers that are not automatically restored. */
|
" subs r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */
|
||||||
" ldmia r0!, {r4-r7} \n"/* Pop low registers. */
|
" ldmia r0!, {r4-r7} \n" /* Pop low registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" bx r3 \n"
|
" bx r3 \n"
|
||||||
" \n"
|
" \n"
|
||||||
|
|
|
@ -87,9 +87,9 @@ extern void vPortYield( void );
|
||||||
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \
|
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \
|
||||||
while( 0 )
|
while( 0 )
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -48,9 +48,9 @@
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M23"
|
#define portARCH_NAME "Cortex-M23"
|
||||||
#define portHAS_ARMV8M_MAIN_EXTENSION 0
|
#define portHAS_ARMV8M_MAIN_EXTENSION 0
|
||||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ARMv8-M common port configurations. */
|
/* ARMv8-M common port configurations. */
|
||||||
|
|
|
@ -81,8 +81,8 @@ typedef unsigned long UBaseType_t;
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 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. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#else
|
#else
|
||||||
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
|
@ -117,7 +117,7 @@ extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGE
|
||||||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
#if ( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
@ -188,13 +188,13 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Settings to define an MPU region.
|
* @brief Settings to define an MPU region.
|
||||||
*/
|
*/
|
||||||
typedef struct MPURegionSettings
|
typedef struct MPURegionSettings
|
||||||
{
|
{
|
||||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||||
} MPURegionSettings_t;
|
} MPURegionSettings_t;
|
||||||
|
|
||||||
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||||
|
@ -203,9 +203,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief System call stack.
|
* @brief System call stack.
|
||||||
*/
|
*/
|
||||||
typedef struct SYSTEM_CALL_STACK_INFO
|
typedef struct SYSTEM_CALL_STACK_INFO
|
||||||
{
|
{
|
||||||
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||||
|
@ -218,74 +218,74 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
|
|
||||||
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU settings as stored in the TCB.
|
* @brief MPU settings as stored in the TCB.
|
||||||
*/
|
*/
|
||||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||||
*
|
*
|
||||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||||
* 16 16 8 8 5 1
|
* 16 16 8 8 5 1
|
||||||
*/
|
*/
|
||||||
#define MAX_CONTEXT_SIZE 54
|
#define MAX_CONTEXT_SIZE 54
|
||||||
|
|
||||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||||
* | | | | PC, xPSR | EXC_RETURN | |
|
* | | | | PC, xPSR | EXC_RETURN | |
|
||||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||||
*
|
*
|
||||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||||
* 16 16 8 8 4 1
|
* 16 16 8 8 4 1
|
||||||
*/
|
*/
|
||||||
#define MAX_CONTEXT_SIZE 53
|
#define MAX_CONTEXT_SIZE 53
|
||||||
|
|
||||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||||
|
|
||||||
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* +----------+-----------------+------------------------------+-----+
|
* +----------+-----------------+------------------------------+-----+
|
||||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||||
* +----------+-----------------+------------------------------+-----+
|
* +----------+-----------------+------------------------------+-----+
|
||||||
*
|
*
|
||||||
* <---------><----------------><------------------------------><---->
|
* <---------><----------------><------------------------------><---->
|
||||||
* 8 8 5 1
|
* 8 8 5 1
|
||||||
*/
|
*/
|
||||||
#define MAX_CONTEXT_SIZE 22
|
#define MAX_CONTEXT_SIZE 22
|
||||||
|
|
||||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* +----------+-----------------+----------------------+-----+
|
* +----------+-----------------+----------------------+-----+
|
||||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||||
* | | PC, xPSR | EXC_RETURN | |
|
* | | PC, xPSR | EXC_RETURN | |
|
||||||
* +----------+-----------------+----------------------+-----+
|
* +----------+-----------------+----------------------+-----+
|
||||||
*
|
*
|
||||||
* <---------><----------------><----------------------><---->
|
* <---------><----------------><----------------------><---->
|
||||||
* 8 8 4 1
|
* 8 8 4 1
|
||||||
*/
|
*/
|
||||||
#define MAX_CONTEXT_SIZE 21
|
#define MAX_CONTEXT_SIZE 21
|
||||||
|
|
||||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||||
|
|
||||||
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||||
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||||
|
|
||||||
typedef struct MPU_SETTINGS
|
typedef struct MPU_SETTINGS
|
||||||
{
|
{
|
||||||
|
@ -364,49 +364,49 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
|
|
||||||
#if ( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allocate a secure context for the task.
|
* @brief Allocate a secure context for the task.
|
||||||
*
|
*
|
||||||
* Tasks are not created with a secure context. Any task that is going to call
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||||
* secure context before it calls any secure function.
|
* secure context before it calls any secure function.
|
||||||
*
|
*
|
||||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||||
*/
|
*/
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when a task is deleted to delete the task's secure context,
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
* if it has one.
|
* if it has one.
|
||||||
*
|
*
|
||||||
* @param[in] pxTCB The TCB of the task being deleted.
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
*/
|
*/
|
||||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the processor is privileged.
|
* @brief Checks whether or not the processor is privileged.
|
||||||
*
|
*
|
||||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raise an SVC request to raise privilege.
|
* @brief Raise an SVC request to raise privilege.
|
||||||
*
|
*
|
||||||
* The SVC handler checks that the SVC was raised from a system call and only
|
* The SVC handler checks that the SVC was raised from a system call and only
|
||||||
* then it raises the privilege. If this is called from any other place,
|
* then it raises the privilege. If this is called from any other place,
|
||||||
* the privilege is not raised.
|
* the privilege is not raised.
|
||||||
*/
|
*/
|
||||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
* register.
|
* register.
|
||||||
*/
|
*/
|
||||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||||
#else
|
#else
|
||||||
#define portIS_PRIVILEGED()
|
#define portIS_PRIVILEGED()
|
||||||
|
@ -419,12 +419,12 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
|
|
||||||
extern BaseType_t xPortIsTaskPrivileged( void );
|
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the calling task is privileged.
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
*
|
*
|
||||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
*/
|
*/
|
||||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||||
|
|
||||||
#endif /* configENABLE_MPU == 1 */
|
#endif /* configENABLE_MPU == 1 */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -439,9 +439,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
* based on whether or not Mainline extension is implemented. */
|
* based on whether or not Mainline extension is implemented. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#else
|
#else
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
#endif
|
#endif
|
||||||
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
@ -450,9 +450,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
*/
|
*/
|
||||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Count the number of leading zeros in a 32-bit value.
|
* @brief Count the number of leading zeros in a 32-bit value.
|
||||||
*/
|
*/
|
||||||
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
{
|
{
|
||||||
uint32_t ulReturn;
|
uint32_t ulReturn;
|
||||||
|
@ -462,7 +462,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
return ulReturn;
|
return ulReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if ( configMAX_PRIORITIES > 32 )
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
|
@ -471,16 +471,16 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Store/clear the ready priorities in a bit map.
|
* @brief Store/clear the ready priorities in a bit map.
|
||||||
*/
|
*/
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the priority of the highest-priority task that is ready to execute.
|
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||||
*/
|
*/
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
* @brief Maximum number of secure contexts.
|
* @brief Maximum number of secure contexts.
|
||||||
*/
|
*/
|
||||||
#ifndef secureconfigMAX_SECURE_CONTEXTS
|
#ifndef secureconfigMAX_SECURE_CONTEXTS
|
||||||
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -164,15 +164,15 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
/* Configure thread mode to use PSP and to be unprivileged. */
|
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||||
}
|
}
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
{
|
{
|
||||||
/* Configure thread mode to use PSP and to be privileged. */
|
/* Configure thread mode to use PSP and to be privileged. */
|
||||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,16 +219,16 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
if( pucStackMemory != NULL )
|
if( pucStackMemory != NULL )
|
||||||
{
|
{
|
||||||
/* Since stack grows down, the starting point will be the last
|
/* Since stack grows down, the starting point will be the last
|
||||||
* location. Note that this location is next to the last
|
* location. Note that this location is next to the last
|
||||||
* allocated byte for stack (excluding the space for seal values)
|
* allocated byte for stack (excluding the space for seal values)
|
||||||
* because the hardware decrements the stack pointer before
|
* because the hardware decrements the stack pointer before
|
||||||
* writing i.e. if stack pointer is 0x2, a push operation will
|
* writing i.e. if stack pointer is 0x2, a push operation will
|
||||||
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
||||||
xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
|
xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
|
||||||
|
|
||||||
/* Seal the created secure process stack. */
|
/* Seal the created secure process stack. */
|
||||||
*( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
||||||
*( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
||||||
|
|
||||||
/* The stack cannot go beyond this location. This value is
|
/* The stack cannot go beyond this location. This value is
|
||||||
* programmed in the PSPLIM register on context switch.*/
|
* programmed in the PSPLIM register on context switch.*/
|
||||||
|
@ -237,32 +237,32 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle;
|
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle;
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
{
|
||||||
|
/* Store the correct CONTROL value for the task on the stack.
|
||||||
|
* This value is programmed in the CONTROL register on
|
||||||
|
* context switch. */
|
||||||
|
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||||
|
pulCurrentStackPointer--;
|
||||||
|
|
||||||
|
if( ulIsTaskPrivileged )
|
||||||
{
|
{
|
||||||
/* Store the correct CONTROL value for the task on the stack.
|
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||||
* This value is programmed in the CONTROL register on
|
|
||||||
* context switch. */
|
|
||||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
|
||||||
pulCurrentStackPointer--;
|
|
||||||
|
|
||||||
if( ulIsTaskPrivileged )
|
|
||||||
{
|
|
||||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store the current stack pointer. This value is programmed in
|
|
||||||
* the PSP register on context switch. */
|
|
||||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the current stack pointer. This value is programmed in
|
||||||
|
* the PSP register on context switch. */
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||||
|
}
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
{
|
{
|
||||||
/* Current SP is set to the starting of the stack. This
|
/* Current SP is set to the starting of the stack. This
|
||||||
* value programmed in the PSP register on context switch. */
|
* value programmed in the PSP register on context switch. */
|
||||||
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
/* Ensure to never return 0 as a valid context handle. */
|
/* Ensure to never return 0 as a valid context handle. */
|
||||||
|
@ -275,7 +275,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
{
|
{
|
||||||
uint32_t ulIPSR, ulSecureContextIndex;
|
uint32_t ulIPSR, ulSecureContextIndex;
|
||||||
|
|
||||||
|
@ -306,7 +307,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
{
|
{
|
||||||
uint8_t * pucStackLimit;
|
uint8_t * pucStackLimit;
|
||||||
uint32_t ulSecureContextIndex;
|
uint32_t ulSecureContextIndex;
|
||||||
|
@ -328,7 +330,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandl
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )
|
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
{
|
{
|
||||||
uint8_t * pucStackLimit;
|
uint8_t * pucStackLimit;
|
||||||
uint32_t ulSecureContextIndex;
|
uint32_t ulSecureContextIndex;
|
||||||
|
|
|
@ -38,12 +38,12 @@
|
||||||
/**
|
/**
|
||||||
* @brief PSP value when no secure context is loaded.
|
* @brief PSP value when no secure context is loaded.
|
||||||
*/
|
*/
|
||||||
#define securecontextNO_STACK 0x0
|
#define securecontextNO_STACK 0x0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Invalid context ID.
|
* @brief Invalid context ID.
|
||||||
*/
|
*/
|
||||||
#define securecontextINVALID_CONTEXT_ID 0UL
|
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -108,7 +108,8 @@ void SecureContext_Init( void );
|
||||||
* @param[in] xSecureContextHandle Context handle corresponding to the
|
* @param[in] xSecureContextHandle Context handle corresponding to the
|
||||||
* context to be freed.
|
* context to be freed.
|
||||||
*/
|
*/
|
||||||
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Loads the given context.
|
* @brief Loads the given context.
|
||||||
|
@ -119,7 +120,8 @@ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void
|
||||||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||||
* to be loaded.
|
* to be loaded.
|
||||||
*/
|
*/
|
||||||
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Saves the given context.
|
* @brief Saves the given context.
|
||||||
|
@ -130,6 +132,7 @@ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void
|
||||||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||||
* to be saved.
|
* to be saved.
|
||||||
*/
|
*/
|
||||||
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle );
|
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
#endif /* __SECURE_CONTEXT_H__ */
|
#endif /* __SECURE_CONTEXT_H__ */
|
||||||
|
|
|
@ -67,7 +67,7 @@
|
||||||
#define secureheapSIZE_MAX ( ~( ( size_t ) 0 ) )
|
#define secureheapSIZE_MAX ( ~( ( size_t ) 0 ) )
|
||||||
|
|
||||||
/* Check if adding a and b will result in overflow. */
|
/* Check if adding a and b will result in overflow. */
|
||||||
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
||||||
|
|
||||||
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
|
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
|
||||||
* the allocation status of a block. When MSB of the xBlockSize member of
|
* the allocation status of a block. When MSB of the xBlockSize member of
|
||||||
|
@ -397,17 +397,17 @@ void * pvPortMalloc( size_t xWantedSize )
|
||||||
traceMALLOC( pvReturn, xWantedSize );
|
traceMALLOC( pvReturn, xWantedSize );
|
||||||
|
|
||||||
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
||||||
|
{
|
||||||
|
if( pvReturn == NULL )
|
||||||
{
|
{
|
||||||
if( pvReturn == NULL )
|
extern void vApplicationMallocFailedHook( void );
|
||||||
{
|
vApplicationMallocFailedHook();
|
||||||
extern void vApplicationMallocFailedHook( void );
|
|
||||||
vApplicationMallocFailedHook();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mtCOVERAGE_TEST_MARKER();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||||
|
|
||||||
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||||
|
|
|
@ -93,7 +93,7 @@ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void )
|
||||||
* permitted. CP11 should be programmed to the same value as CP10. */
|
* permitted. CP11 should be programmed to the same value as CP10. */
|
||||||
*( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK );
|
*( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK );
|
||||||
|
|
||||||
/* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures
|
/* LSPENS = 0 ==> LSPEN is writable from non-secure state. This ensures
|
||||||
* that we can enable/disable lazy stacking in port.c file. */
|
* that we can enable/disable lazy stacking in port.c file. */
|
||||||
*( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK );
|
*( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK );
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -46,127 +46,127 @@
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" program_mpu_first_task: \n"
|
" program_mpu_first_task: \n"
|
||||||
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||||
" \n"
|
" \n"
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
" movs r3, #1 \n" /* r3 = 1. */
|
" movs r3, #1 \n" /* r3 = 1. */
|
||||||
" bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */
|
" bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */
|
||||||
" str r2, [r1] \n" /* Disable MPU. */
|
" str r2, [r1] \n" /* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r1, [r2] \n" /* Program MAIR0. */
|
" str r1, [r2] \n" /* Program MAIR0. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||||
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
" ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||||
" \n"
|
" \n"
|
||||||
" movs r3, #4 \n" /* r3 = 4. */
|
" movs r3, #4 \n" /* r3 = 4. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||||
" ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */
|
||||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */
|
" stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */
|
||||||
" movs r3, #5 \n" /* r3 = 5. */
|
" movs r3, #5 \n" /* r3 = 5. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 5. */
|
" str r3, [r1] \n" /* Program RNR = 5. */
|
||||||
" ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */
|
||||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */
|
" stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */
|
||||||
" movs r3, #6 \n" /* r3 = 6. */
|
" movs r3, #6 \n" /* r3 = 6. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 6. */
|
" str r3, [r1] \n" /* Program RNR = 6. */
|
||||||
" ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */
|
||||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */
|
" stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */
|
||||||
" movs r3, #7 \n" /* r3 = 6. */
|
" movs r3, #7 \n" /* r3 = 6. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 7. */
|
" str r3, [r1] \n" /* Program RNR = 7. */
|
||||||
" ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */
|
||||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */
|
" stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
" movs r3, #1 \n" /* r3 = 1. */
|
" movs r3, #1 \n" /* r3 = 1. */
|
||||||
" orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */
|
" orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */
|
||||||
" str r2, [r1] \n" /* Enable MPU. */
|
" str r2, [r1] \n" /* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n" /* Force memory writes before continuing. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_context_first_task: \n"
|
" restore_context_first_task: \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_special_regs_first_task: \n"
|
" restore_special_regs_first_task: \n"
|
||||||
" subs r1, #16 \n"
|
" subs r1, #16 \n"
|
||||||
" ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */
|
" ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */
|
||||||
" subs r1, #16 \n"
|
" subs r1, #16 \n"
|
||||||
" msr psp, r2 \n"
|
" msr psp, r2 \n"
|
||||||
" msr psplim, r3 \n"
|
" msr psplim, r3 \n"
|
||||||
" msr control, r4 \n"
|
" msr control, r4 \n"
|
||||||
" mov lr, r5 \n"
|
" mov lr, r5 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" restore_general_regs_first_task: \n"
|
" restore_general_regs_first_task: \n"
|
||||||
" subs r1, #32 \n"
|
" subs r1, #32 \n"
|
||||||
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */
|
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */
|
||||||
" stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */
|
" stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */
|
||||||
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */
|
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */
|
||||||
" stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */
|
" stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */
|
||||||
" subs r1, #48 \n"
|
" subs r1, #48 \n"
|
||||||
" ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */
|
" ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */
|
||||||
" mov r8, r4 \n" /* r8 = r4. */
|
" mov r8, r4 \n" /* r8 = r4. */
|
||||||
" mov r9, r5 \n" /* r9 = r5. */
|
" mov r9, r5 \n" /* r9 = r5. */
|
||||||
" mov r10, r6 \n" /* r10 = r6. */
|
" mov r10, r6 \n" /* r10 = r6. */
|
||||||
" mov r11, r7 \n" /* r11 = r7. */
|
" mov r11, r7 \n" /* r11 = r7. */
|
||||||
" subs r1, #32 \n"
|
" subs r1, #32 \n"
|
||||||
" ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */
|
" ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */
|
||||||
" subs r1, #16 \n"
|
" subs r1, #16 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" restore_context_done_first_task: \n"
|
" restore_context_done_first_task: \n"
|
||||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
" pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
" xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||||
" xMAIR0Const2: .word 0xe000edc0 \n"
|
" xMAIR0Const2: .word 0xe000edc0 \n"
|
||||||
" xRNRConst2: .word 0xe000ed98 \n"
|
" xRNRConst2: .word 0xe000ed98 \n"
|
||||||
" xRBARConst2: .word 0xe000ed9c \n"
|
" xRBARConst2: .word 0xe000ed9c \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||||
" ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
" ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||||
" msr psplim, r1 \n"/* Set this task's PSPLIM value. */
|
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
||||||
" movs r1, #2 \n"/* r1 = 2. */
|
" movs r1, #2 \n" /* r1 = 2. */
|
||||||
" msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */
|
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||||
" adds r0, #32 \n"/* Discard everything up to r0. */
|
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx r2 \n"/* Finally, branch to EXC_RETURN. */
|
" bx r2 \n" /* Finally, branch to EXC_RETURN. */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -177,15 +177,15 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
" movs r1, #1 \n"/* r1 = 1. */
|
" movs r1, #1 \n" /* r1 = 1. */
|
||||||
" tst r0, r1 \n"/* Perform r0 & r1 (bitwise AND) and update the conditions flag. */
|
" tst r0, r1 \n" /* Perform r0 & r1 (bitwise AND) and update the conditions flag. */
|
||||||
" beq running_privileged \n"/* If the result of previous AND operation was 0, branch. */
|
" beq running_privileged \n" /* If the result of previous AND operation was 0, branch. */
|
||||||
" movs r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
" movs r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||||
" bx lr \n"/* Return. */
|
" bx lr \n" /* Return. */
|
||||||
" running_privileged: \n"
|
" running_privileged: \n"
|
||||||
" movs r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
" movs r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||||
" bx lr \n"/* Return. */
|
" bx lr \n" /* Return. */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
::: "r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
|
@ -199,11 +199,11 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, control \n"/* Read the CONTROL register. */
|
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||||
" movs r1, #1 \n"/* r1 = 1. */
|
" movs r1, #1 \n" /* r1 = 1. */
|
||||||
" bics r0, r1 \n"/* Clear the bit 0. */
|
" bics r0, r1 \n" /* Clear the bit 0. */
|
||||||
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||||
" bx lr \n"/* Return to the caller. */
|
" bx lr \n" /* Return to the caller. */
|
||||||
::: "r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -215,11 +215,11 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, control \n"/* r0 = CONTROL. */
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
" movs r1, #1 \n"/* r1 = 1. */
|
" movs r1, #1 \n" /* r1 = 1. */
|
||||||
" orrs r0, r1 \n"/* r0 = r0 | r1. */
|
" orrs r0, r1 \n" /* r0 = r0 | r1. */
|
||||||
" msr control, r0 \n"/* CONTROL = r0. */
|
" msr control, r0 \n" /* CONTROL = r0. */
|
||||||
" bx lr \n"/* Return to the caller. */
|
" bx lr \n" /* Return to the caller. */
|
||||||
::: "r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -231,14 +231,14 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
||||||
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
||||||
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
||||||
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||||
" cpsie i \n"/* Globally enable interrupts. */
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" svc %0 \n"/* System call to start the first task. */
|
" svc %0 \n" /* System call to start the first task. */
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
|
@ -277,254 +277,254 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||||
" ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */
|
" ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */
|
||||||
" mrs r2, psp \n" /* r2 = PSP. */
|
" mrs r2, psp \n" /* r2 = PSP. */
|
||||||
" \n"
|
" \n"
|
||||||
" save_general_regs: \n"
|
" save_general_regs: \n"
|
||||||
" stmia r1!, {r4-r7} \n" /* Store r4-r7. */
|
" stmia r1!, {r4-r7} \n" /* Store r4-r7. */
|
||||||
" mov r4, r8 \n" /* r4 = r8. */
|
" mov r4, r8 \n" /* r4 = r8. */
|
||||||
" mov r5, r9 \n" /* r5 = r9. */
|
" mov r5, r9 \n" /* r5 = r9. */
|
||||||
" mov r6, r10 \n" /* r6 = r10. */
|
" mov r6, r10 \n" /* r6 = r10. */
|
||||||
" mov r7, r11 \n" /* r7 = r11. */
|
" mov r7, r11 \n" /* r7 = r11. */
|
||||||
" stmia r1!, {r4-r7} \n" /* Store r8-r11. */
|
" stmia r1!, {r4-r7} \n" /* Store r8-r11. */
|
||||||
" ldmia r2!, {r4-r7} \n" /* Copy half of the hardware saved context into r4-r7. */
|
" ldmia r2!, {r4-r7} \n" /* Copy half of the hardware saved context into r4-r7. */
|
||||||
" stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */
|
" stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */
|
||||||
" ldmia r2!, {r4-r7} \n" /* Copy rest half of the hardware saved context into r4-r7. */
|
" ldmia r2!, {r4-r7} \n" /* Copy rest half of the hardware saved context into r4-r7. */
|
||||||
" stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */
|
" stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */
|
||||||
" \n"
|
" \n"
|
||||||
" save_special_regs: \n"
|
" save_special_regs: \n"
|
||||||
" mrs r2, psp \n" /* r2 = PSP. */
|
" mrs r2, psp \n" /* r2 = PSP. */
|
||||||
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
||||||
" mrs r4, control \n" /* r4 = CONTROL. */
|
" mrs r4, control \n" /* r4 = CONTROL. */
|
||||||
" mov r5, lr \n" /* r5 = LR. */
|
" mov r5, lr \n" /* r5 = LR. */
|
||||||
" stmia r1!, {r2-r5} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
" stmia r1!, {r2-r5} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||||
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" select_next_task: \n"
|
" select_next_task: \n"
|
||||||
" cpsid i \n"
|
" cpsid i \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" cpsie i \n"
|
" cpsie i \n"
|
||||||
" \n"
|
" \n"
|
||||||
" program_mpu: \n"
|
" program_mpu: \n"
|
||||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||||
" \n"
|
" \n"
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
" movs r3, #1 \n" /* r3 = 1. */
|
" movs r3, #1 \n" /* r3 = 1. */
|
||||||
" bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */
|
" bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */
|
||||||
" str r2, [r1] \n" /* Disable MPU. */
|
" str r2, [r1] \n" /* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||||
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r1, [r2] \n" /* Program MAIR0. */
|
" str r1, [r2] \n" /* Program MAIR0. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||||
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
" ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||||
" \n"
|
" \n"
|
||||||
" movs r3, #4 \n" /* r3 = 4. */
|
" movs r3, #4 \n" /* r3 = 4. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 4. */
|
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||||
" ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */
|
||||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */
|
" stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */
|
||||||
" movs r3, #5 \n" /* r3 = 5. */
|
" movs r3, #5 \n" /* r3 = 5. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 5. */
|
" str r3, [r1] \n" /* Program RNR = 5. */
|
||||||
" ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */
|
||||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */
|
" stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */
|
||||||
" movs r3, #6 \n" /* r3 = 6. */
|
" movs r3, #6 \n" /* r3 = 6. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 6. */
|
" str r3, [r1] \n" /* Program RNR = 6. */
|
||||||
" ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */
|
||||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */
|
" stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */
|
||||||
" movs r3, #7 \n" /* r3 = 6. */
|
" movs r3, #7 \n" /* r3 = 6. */
|
||||||
" str r3, [r1] \n" /* Program RNR = 7. */
|
" str r3, [r1] \n" /* Program RNR = 7. */
|
||||||
" ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */
|
" ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */
|
||||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */
|
" stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
" movs r3, #1 \n" /* r3 = 1. */
|
" movs r3, #1 \n" /* r3 = 1. */
|
||||||
" orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */
|
" orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */
|
||||||
" str r2, [r1] \n" /* Enable MPU. */
|
" str r2, [r1] \n" /* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n" /* Force memory writes before continuing. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_context: \n"
|
" restore_context: \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_special_regs: \n"
|
" restore_special_regs: \n"
|
||||||
" subs r1, #16 \n"
|
" subs r1, #16 \n"
|
||||||
" ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */
|
" ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */
|
||||||
" subs r1, #16 \n"
|
" subs r1, #16 \n"
|
||||||
" msr psp, r2 \n"
|
" msr psp, r2 \n"
|
||||||
" msr psplim, r3 \n"
|
" msr psplim, r3 \n"
|
||||||
" msr control, r4 \n"
|
" msr control, r4 \n"
|
||||||
" mov lr, r5 \n"
|
" mov lr, r5 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" restore_general_regs: \n"
|
" restore_general_regs: \n"
|
||||||
" subs r1, #32 \n"
|
" subs r1, #32 \n"
|
||||||
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */
|
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */
|
||||||
" stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */
|
" stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */
|
||||||
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */
|
" ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */
|
||||||
" stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */
|
" stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */
|
||||||
" subs r1, #48 \n"
|
" subs r1, #48 \n"
|
||||||
" ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */
|
" ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */
|
||||||
" mov r8, r4 \n" /* r8 = r4. */
|
" mov r8, r4 \n" /* r8 = r4. */
|
||||||
" mov r9, r5 \n" /* r9 = r5. */
|
" mov r9, r5 \n" /* r9 = r5. */
|
||||||
" mov r10, r6 \n" /* r10 = r6. */
|
" mov r10, r6 \n" /* r10 = r6. */
|
||||||
" mov r11, r7 \n" /* r11 = r7. */
|
" mov r11, r7 \n" /* r11 = r7. */
|
||||||
" subs r1, #32 \n"
|
" subs r1, #32 \n"
|
||||||
" ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */
|
" ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */
|
||||||
" subs r1, #16 \n"
|
" subs r1, #16 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" restore_context_done: \n"
|
" restore_context_done: \n"
|
||||||
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
" pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
" xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||||
" xMAIR0Const: .word 0xe000edc0 \n"
|
" xMAIR0Const: .word 0xe000edc0 \n"
|
||||||
" xRNRConst: .word 0xe000ed98 \n"
|
" xRNRConst: .word 0xe000ed98 \n"
|
||||||
" xRBARConst: .word 0xe000ed9c \n"
|
" xRBARConst: .word 0xe000ed9c \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, psp \n"/* Read PSP in r0. */
|
" mrs r0, psp \n" /* Read PSP in r0. */
|
||||||
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||||
" subs r0, r0, #40 \n"/* Make space for PSPLIM, LR and the remaining registers on the stack. */
|
" subs r0, r0, #40 \n" /* Make space for PSPLIM, LR and the remaining registers on the stack. */
|
||||||
" str r0, [r1] \n"/* Save the new top of stack in TCB. */
|
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
|
||||||
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||||
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||||
" stmia r0!, {r2-r7} \n"/* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */
|
" stmia r0!, {r2-r7} \n" /* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */
|
||||||
" mov r4, r8 \n"/* r4 = r8. */
|
" mov r4, r8 \n" /* r4 = r8. */
|
||||||
" mov r5, r9 \n"/* r5 = r9. */
|
" mov r5, r9 \n" /* r5 = r9. */
|
||||||
" mov r6, r10 \n"/* r6 = r10. */
|
" mov r6, r10 \n" /* r6 = r10. */
|
||||||
" mov r7, r11 \n"/* r7 = r11. */
|
" mov r7, r11 \n" /* r7 = r11. */
|
||||||
" stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */
|
" stmia r0!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
|
||||||
" \n"
|
" \n"
|
||||||
" cpsid i \n"
|
" cpsid i \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" cpsie i \n"
|
" cpsie i \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||||
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r0, r0, #24 \n"/* Move to the high registers. */
|
" adds r0, r0, #24 \n" /* Move to the high registers. */
|
||||||
" ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */
|
" ldmia r0!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */
|
||||||
" mov r8, r4 \n"/* r8 = r4. */
|
" mov r8, r4 \n" /* r8 = r4. */
|
||||||
" mov r9, r5 \n"/* r9 = r5. */
|
" mov r9, r5 \n" /* r9 = r5. */
|
||||||
" mov r10, r6 \n"/* r10 = r6. */
|
" mov r10, r6 \n" /* r10 = r6. */
|
||||||
" mov r11, r7 \n"/* r11 = r7. */
|
" mov r11, r7 \n" /* r11 = r7. */
|
||||||
" msr psp, r0 \n"/* Remember the new top of stack for the task. */
|
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
||||||
" subs r0, r0, #40 \n"/* Move to the starting of the saved context. */
|
" subs r0, r0, #40 \n" /* Move to the starting of the saved context. */
|
||||||
" ldmia r0!, {r2-r7} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */
|
" ldmia r0!, {r2-r7} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */
|
||||||
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
|
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
||||||
" bx r3 \n"
|
" bx r3 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
".syntax unified \n"
|
".syntax unified \n"
|
||||||
".extern vPortSVCHandler_C \n"
|
".extern vPortSVCHandler_C \n"
|
||||||
".extern vSystemCallEnter \n"
|
".extern vSystemCallEnter \n"
|
||||||
".extern vSystemCallEnter_1 \n"
|
".extern vSystemCallEnter_1 \n"
|
||||||
".extern vSystemCallExit \n"
|
".extern vSystemCallExit \n"
|
||||||
" \n"
|
" \n"
|
||||||
"movs r0, #4 \n"
|
"movs r0, #4 \n"
|
||||||
"mov r1, lr \n"
|
"mov r1, lr \n"
|
||||||
"tst r0, r1 \n"
|
"tst r0, r1 \n"
|
||||||
"beq stack_on_msp \n"
|
"beq stack_on_msp \n"
|
||||||
"stack_on_psp: \n"
|
"stack_on_psp: \n"
|
||||||
" mrs r0, psp \n"
|
" mrs r0, psp \n"
|
||||||
" b route_svc \n"
|
" b route_svc \n"
|
||||||
"stack_on_msp: \n"
|
"stack_on_msp: \n"
|
||||||
" mrs r0, msp \n"
|
" mrs r0, msp \n"
|
||||||
" b route_svc \n"
|
" b route_svc \n"
|
||||||
" \n"
|
" \n"
|
||||||
"route_svc: \n"
|
"route_svc: \n"
|
||||||
" ldr r2, [r0, #24] \n"
|
" ldr r2, [r0, #24] \n"
|
||||||
" subs r2, #2 \n"
|
" subs r2, #2 \n"
|
||||||
" ldrb r3, [r2, #0] \n"
|
" ldrb r3, [r2, #0] \n"
|
||||||
" cmp r3, %0 \n"
|
" cmp r3, %0 \n"
|
||||||
" beq system_call_enter \n"
|
" beq system_call_enter \n"
|
||||||
" cmp r3, %1 \n"
|
" cmp r3, %1 \n"
|
||||||
" beq system_call_enter_1 \n"
|
" beq system_call_enter_1 \n"
|
||||||
" cmp r3, %2 \n"
|
" cmp r3, %2 \n"
|
||||||
" beq system_call_exit \n"
|
" beq system_call_exit \n"
|
||||||
" b vPortSVCHandler_C \n"
|
" b vPortSVCHandler_C \n"
|
||||||
" \n"
|
" \n"
|
||||||
"system_call_enter: \n"
|
"system_call_enter: \n"
|
||||||
" b vSystemCallEnter \n"
|
" b vSystemCallEnter \n"
|
||||||
"system_call_enter_1: \n"
|
"system_call_enter_1: \n"
|
||||||
" b vSystemCallEnter_1 \n"
|
" b vSystemCallEnter_1 \n"
|
||||||
"system_call_exit: \n"
|
"system_call_exit: \n"
|
||||||
" b vSystemCallExit \n"
|
" b vSystemCallExit \n"
|
||||||
" \n"
|
" \n"
|
||||||
: /* No outputs. */
|
: /* No outputs. */
|
||||||
:"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
: "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||||
: "r0", "r1", "r2", "r3", "memory"
|
: "r0", "r1", "r2", "r3", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" movs r0, #4 \n"
|
" movs r0, #4 \n"
|
||||||
" mov r1, lr \n"
|
" mov r1, lr \n"
|
||||||
" tst r0, r1 \n"
|
" tst r0, r1 \n"
|
||||||
" beq stacking_used_msp \n"
|
" beq stacking_used_msp \n"
|
||||||
" mrs r0, psp \n"
|
" mrs r0, psp \n"
|
||||||
" ldr r2, svchandler_address_const \n"
|
" ldr r2, svchandler_address_const \n"
|
||||||
" bx r2 \n"
|
" bx r2 \n"
|
||||||
" stacking_used_msp: \n"
|
" stacking_used_msp: \n"
|
||||||
" mrs r0, msp \n"
|
" mrs r0, msp \n"
|
||||||
" ldr r2, svchandler_address_const \n"
|
" ldr r2, svchandler_address_const \n"
|
||||||
" bx r2 \n"
|
" bx r2 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
@ -48,9 +48,9 @@
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M23"
|
#define portARCH_NAME "Cortex-M23"
|
||||||
#define portHAS_ARMV8M_MAIN_EXTENSION 0
|
#define portHAS_ARMV8M_MAIN_EXTENSION 0
|
||||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ARMv8-M common port configurations. */
|
/* ARMv8-M common port configurations. */
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue